赞
踩
从结果中可以看到,我们实现了开篇中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;
- }
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
泛型牛逼的地方就是在这个地方。
如果你不用泛型,而使用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);
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
这个时候,这个T,使用起来就像使用我们常用的一般对象一样,我这的参数是个List类型,当然也可是其他类型的,姿势都一样。
然后是具体调用的地方的代码
- List<ProbeObject> list = Lists.newArrayList();
- listAddAllAvoidNPE(list, decoder.getProperties());
这个方法的第二个参数的返回值可能是null,所以,直接调用addAll(),就会抛空指针异常。所以,就如上,那么一提取。就好多啦。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。