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函数会直接返回子类的对象。再也不用以前那样做判断了

原文地址:https://www.cnblogs.com/gaoxing/p/4370298.html