美文网首页
Java 泛型相关

Java 泛型相关

作者: zhaoyubetter | 来源:发表于2017-11-30 13:20 被阅读12次

    参考:

    http://mp.weixin.qq.com/s?__biz=MzI3ODc3NzQ4NQ==&mid=2247483915&idx=1&sn=6149889e1dea20c526e511b8903d549d&chksm=eb5099e9dc2710ff917a6c28d81de9a38772a2ddbb2f3ec22d43294296eeaf35af86e7e66b75&mpshare=1&scene=23&srcid=1130PIsF5F5QUADlrFikXuey#rd

    泛型的作用:

    解决类型的转换问题,避免转换错误(CastException)、类型自动推断;

    原生态是什么意思?

    不定义<> 表示原生态类型(获取class对象时,需要用原生态类型,因为编译时被擦除);

    1. Java泛型是如何工作的,什么是泛型擦除?

    Java泛型是通过类型擦除实现的,编译时会擦除泛型相关的信息,运行时不存在泛型的信息,比如:
    List<Integer> 在运行时,其实是 List;
    为什么要这么做呢?这是因为兼容jdk1.5以前的版本,不得不说Java用心良苦;
    泛型擦除也就是在编译成字节码之前先对类型进行检查,然后再擦除(所有类型参数都用限定的类型替换,包括类、变量、方法)如果调用泛型返回,擦除时,插入强制类型转换;

    2.Java 泛型类、泛型接口、泛型方法有和区别?

    1. 泛型类是在实例化时才能确定的类型,也就是实例化时,必须明确指定具体类型;(class Test<T>{},实例化时,必须指定T的类型);
    2. 接口与泛型类一致;
    3. 泛型方法所在的类可是泛型类,也可不是,如非必要,尽可能使用泛型方法;
    static <T> void method2(List<T> list) {
           for (T t : list) {
           }
       }
    

    Java 的泛型机制虽然在编译期间进行了擦除,但是在编译 Java 源代码成 class 文件中还是保存了泛型相关的信息,这些信息被保存在 class 字节码的常量池中,使用了泛型的代码处会生成一个 signature 签名字段,通过签名 signature 字段指明这个常量池的地址,JDK 提供了方法去读取这些泛型信息的方法,然后再借助反射就可以获得泛型参数的具体类型:

    如下例子:

    class MyTest {
    
        static void main(String[] bb) {
            // 获取父泛型
            ParameterizedType type = (ParameterizedType) Bar.class.getGenericSuperclass();
            System.out.println(type.getActualTypeArguments())  // [class java.lang.String]
    
            // 获取成员域的泛型
            ParameterizedType type2 = Foo.class.getDeclaredField("children").getGenericType();
            System.out.println(type2.getActualTypeArguments())  // [class MyTest$Bar]
    
            // 获取 方法参数 的泛型
            ParameterizedType paramType = (ParameterizedType) Foo.class.getMethod("foo", List.class).getGenericParameterTypes()[0];
            System.out.println(paramType.getActualTypeArguments()[0])   // class java.lang.String
    
            // 获取类的泛型
            System.out.println(Foo.class.getTypeParameters()[0].getBounds()[0])  // interface java.lang.CharSequence
    
        }
    
    
        static class Foo<T extends CharSequence> {
            public List<Bar> children = new ArrayList<Bar>();
    
            List<StringBuilder> foo(List<String> foo) { return null; }
    
            void bar(List<? extends String> param) {
            }
        }
    
        static class Bar extends Foo<String> {}
    
    
    }
    

    相关文章

      网友评论

          本文标题:Java 泛型相关

          本文链接:https://www.haomeiwen.com/subject/nbqvbxtx.html