泛型不允许使用instanceof?为何这段WeakReference代码可编译?
关于泛型与instanceof的疑惑解答
首先明确:你遇到的这个现象,核心原因是Java的泛型类型擦除机制。
你之前了解的“泛型不允许使用instanceof”,准确表述是:无法在运行时检查泛型的实际类型参数。因为Java泛型是编译期特性,编译完成后所有泛型信息都会被擦除,JVM运行时根本不知道WeakReference<String>和WeakReference<Integer>有什么区别,它们都会被还原为原始类型WeakReference。
看你贴的代码:
WeakReference<String> ps = new WeakReference<>(new String()); if (ps instanceof WeakReference<String>) { System.out.println("Ok"); }
编译器会自动把instanceof后面的泛型参数<String>擦除,实际编译后的代码等价于:
if (ps instanceof WeakReference) { System.out.println("Ok"); }
也就是说,这个判断本质上只是检查ps是不是WeakReference的实例,泛型参数在运行时完全不起作用。你可以做个测试:如果把ps改成WeakReference<Integer>,这个判断依然会返回true,因为运行时只认原始类型。
之所以编译器允许你写WeakReference<String>这种带泛型的写法,只是语法上的兼容,让代码看起来更清晰,但实际运行时不会做任何泛型类型的检查。如果真的想尝试检查泛型参数(比如instanceof WeakReference<String>严格匹配),这在Java里是做不到的,因为类型擦除已经把这部分信息抹掉了。
内容的提问来源于stack exchange,提问作者mike
相关产品推荐
相关产品推荐

