微信公众号:路人zhang
网站救助计划

1.为阅读体验,本站无任何广告,也无任何盈利方法,站长一直在用爱发电,现濒临倒闭,希望有能力的同学能帮忙分担服务器成本


2.捐助10元及以上同学,可添加站长微信lurenzhang888,备注捐助网站倒闭后可联系站长领取本站pdf内容


3.若网站能存活下来,后续将会持续更新内容

当前位置: Java > Java基础高频面试题 > 44. JAVA泛型

Java泛型是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。

  • 泛型擦除(这是面试考察泛型时经常问到的问题)

Java的泛型基本上都是在编译器这个层次上实现的,在生成的字节码中是不包含泛型中的类型信息的,使用泛型的时候加上类型参数,在编译器编译的时候会去掉,这个过程成为类型擦除。看下面代码

public class Main{
    public static void main(String[] args) {
        ArrayList<Integer> arrayList1 = new ArrayList<>();
        ArrayList<String> arrayList2 = new ArrayList<>();

        System.out.println(arrayList1.getClass() == arrayList2.getClass());
    }
}

输出结果

true

可以看到ArrayList<Integer>ArrayList<String>的原始类型是相同,在编译成字节码文件后都会变成List,JVM看到的只有List,看不到泛型信息,这就是泛型的类型擦除。在看下面这段代码

public class Main{
    public static void main(String[] args) throws Exception {
        ArrayList<Integer> arrayList = new ArrayList<>();
        arrayList.add(1);
        arrayList.getClass().getMethod("add", Object.class).invoke(arrayList, "a");
        System.out.println(arrayList.get(0));
        System.out.println(arrayList.get(1));
    }
}

输出

1
a

可以看到通过反射进行add操作,ArrayList<Integer>竟然可以存储字符串,这是因为在反射就是在运行期调用的add方法,在运行期泛型信息已经被擦除。

  • 既然存在类型擦除,那么Java是如何保证在ArrayList<Integer>添加字符串会报错呢?

Java编译器是通过先检查代码中泛型的类型,然后在进行类型擦除,再进行编译。

本站链接:https://www.mianshi.online如需勘误或投稿,请联系微信:lurenzhang888


点击面试手册,获取本站面试手册PDF完整版