从结果中可以看到,我们实现了开篇中IntegerPoint类和FloatPoint类的效果。下面来看看泛型是怎么定义及使用的吧。
(1)、定义泛型:Point<T>
首先,大家可以看到Point<T>,即在类名后面加一个尖括号,括号里是一个大写字母。这里写的是T,其实这个字母可以是任何大写字母,大家这里先记着,可以是任何大写字母,意义是相同的。
(2)类中使用泛型
这个T表示派生自Object类的任何类,比如String,Integer,Double等等。这里要注意的是,T一定是派生于Object类的。为方便起见,大家可以在这里把T当成String,即String在类中怎么用,那T在类中就可以怎么用!所以下面的:定义变量,作为返回值,作为参数传入的定义就很容易理解了。
可以看到,当我们构造时使用的是String,而在setVar时,传进去Integer类型时,就会报错。而不是像Object实现方式一样,在运行时才会报强制转换错误。
在接口上定义泛型与在类中定义泛型是一样的,代码如下:
与泛型类的定义一样,也是在接口名后加尖括号;
(1)、使用方法一:非泛型类
但是在使用的时候,就出现问题了,我们先看看下面这个使用方法:
在方法一中,我们在类中直接把Info<T>接口给填充好了,但我们的类,是可以构造成泛型类的,那我们利用泛型类来构造填充泛型接口会是怎样呢?
最关键的是构造泛型类的过程:首先,我们看静态泛型函数的使用方法:
转自:http://blog.csdn.net/harvic880925/article/details/49872903
-
import lombok.Data;
-
-
@Data
-
public
class MultiObject<T> {
-
-
/**
-
* 成功状态
-
*/
-
private
boolean success;
-
-
/**
-
* 异常
-
*/
-
private Exception ex;
-
-
/**
-
* 数据
-
*/
-
private T obj;
-
-
public MultiObject() {
-
}
-
-
/**
-
* 注意:当传入的泛型是Boolean时,就和第三个构造函数冲突了。
-
*/
-
public MultiObject(boolean success) {
-
this.success = success;
-
}
-
-
public MultiObject(Exception ex) {
-
this.success =
false;
-
this.ex = ex;
-
}
-
-
public MultiObject(T value) {
-
this.success =
true;
-
this.obj = value;
-
}
-
}
泛型牛逼的地方就是在这个地方。
如果你不用泛型,而使用Object类型,那么每次执行完之后,我们即使得到这个结果,还得类型转换一下,那么这下就像文章上面描述的那样。分分钟出现castfailexception。也就是类型转换异常啦。
但是,若是使用了这个泛型之后,那么我们的某个操作所需要的返回结果是什么类型,就可以 传入什么类型,而且在实际取得返回结果的时候,就不需要使用类型转换,这样就很好的达到了目的。
这个主要是代码设计层次的提高。写再多的业务代码,要是不提高,那么写的都是渣。
关于,这个model代码里面为啥没有getter和setter,都是因为使用@Data这个注解,可以自动填充这个getter和setter。所以。就表在意这个问题啦。在其他地方可以正常使用各个属性getter和setter方法,虽然这些方法,你暂时看不见。有兴趣的可以了解下lombok。
恰巧我都使用过,就正好记录一下实际使用实例。
-
/**
-
* 将Json字符串信息转换成对应的Java对象
-
*
-
* @param json json字符串对象
-
* @param c 对应的类型
-
*/
-
public
static <T>
T parseJsonToObj(String json, Class<T> c) {
-
try {
-
JSONObject jsonObject = JSONObject.parseObject(json);
-
return JSON.toJavaObject(jsonObject, c);
-
}
catch (Exception e) {
-
LOG.error(e.getMessage());
-
}
-
return
null;
-
}
然后是具体调用的地方的代码。
-
Collector collectorObj = JSONUtils.parseJsonToObj(collector, Collector.class);
-
Flume flume = JSONUtils.parseJsonToObj(flumeJson, Flume.class);
-
Probe probe = JSONUtils.parseJsonToObj(probeJson, Probe.class);
可以看到,真的只是因为传入的参数类型不一样,但若你不知道泛型的话,那你就得没遇到一个类型的转换,你就得写一个这么个方法。
-
/**
-
* @param dest 目的集合
-
* @param source 源集合
-
* @param <T> 集合参数的类型
-
*/
-
private
static <T>
void listAddAllAvoidNPE(List<T> dest, List<T> source) {
-
if (source ==
null) {
-
return;
-
}
-
dest.addAll(source);
-
}
-
-
private
static <T>
void listAddAvoidNull(List<T> dest, T source) {
-
if (source ==
null) {
-
return;
-
}
-
dest.add(source);
-
}
这个时候,这个T,使用起来就像使用我们常用的一般对象一样,我这的参数是个List类型,当然也可是其他类型的,姿势都一样。
然后是具体调用的地方的代码
-
List<ProbeObject> list = Lists.newArrayList();
-
listAddAllAvoidNPE(list, decoder.getProperties());
这个方法的第二个参数的返回值可能是null,所以,直接调用addAll(),就会抛空指针异常。所以,就如上,那么一提取。就好多啦。
本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。