java的泛型的技巧
最近学习scala,了解了两个概念:class和type,什么是class,就是具有相同的class对象,List<String> ,List<Integer>具有相同的class, 什么是type,就是对象的绝对类型。List<String>和List<Integer>是不同的Type;
java 中的泛型在运行时是擦除的。但是我们可以通过反射的方法获得泛型的类型,在有的时候非常有用。
public class GenericTest { private Map<String , Integer> map = new HashMap<String, Integer>(); public static void main(String[] args) throws SecurityException, NoSuchFieldException { // 获取Class实例 Class<GenericTest> class1 = GenericTest.class; // 根据属性名取得该属性对应的Field对象 Field mapField = class1.getDeclaredField("map"); // 示范第一个方法:直接通过getType()取出Field的类型,只对普通类型的Field有效 Class<?> class2 = mapField.getType(); // 输出查看 System.out.println("属性名为map的属性类型为:"+class2); // 示范第二种方法: Type mapMainType = mapField.getGenericType(); // 为了确保安全转换,使用instanceof if (mapMainType instanceof ParameterizedType) { // 执行强制类型转换 ParameterizedType parameterizedType = (ParameterizedType)mapMainType; // 获取基本类型信息,即Map Type basicType = parameterizedType.getRawType(); System.out.println("基本类型为:"+basicType); // 获取泛型类型的泛型参数 Type[] types = parameterizedType.getActualTypeArguments(); for (int i = 0; i < types.length; i++) { System.out.println("第"+(i+1)+"个泛型类型是:"+types[i]); } } else { System.out.println("获取泛型类型出错!"); } } }
最近看netty的源码发现泛型一个很有用的技巧:父类使用子类的类型作为泛型,然后返回
public abstract class AbstractBootstrap<B extends AbstractBootstrap<B, C>, C extends Channel> implements Cloneable { public B group(EventLoopGroup group) { if (group == null) { throw new NullPointerException("group"); } if (this.group != null) { throw new IllegalStateException("group set already"); } this.group = group; return (B) this; } }
这是父类的实现,使用子类的类型作为泛型。
public class Bootstrap extends AbstractBootstrap<Bootstrap, Channel> {}
子类的类签名,在调用父类的goup函数会直接返回子类的对象。再也不用以前那样做判断了