将instanceof与泛型一起使用

mik*_*ike 5 java

我正在阅读有关泛型的内容,并且了解到它们不允许使用instanceof. 但是,以下代码可以编译:

WeakReference<String> ps = new WeakReference<>(new String());
if (ps instanceof WeakReference<String>) {
    System.out.println("Ok");
}
Run Code Online (Sandbox Code Playgroud)

谁能澄清我不明白的事情吗?

Swe*_*per 6

检查 a 是否WeakReference<String>为 aWeakReference<String>不需要运行时检查有关泛型类型的任何内容。毕竟,这确实是事实。

\n

更有意义/有用的例子是:

\n
List<String> x = new LinkedList<>();\nif (x instanceof ArrayList<String>) {\n    System.out.println("Ok");\n}\n
Run Code Online (Sandbox Code Playgroud)\n
List<Integer> x = new LinkedList<>();\nif (x instanceof ArrayList<? extends Number>) {\n    System.out.println("Ok");\n}\n
Run Code Online (Sandbox Code Playgroud)\n

在这两种情况下,都可以在编译时检查“泛型部分”。只有当您需要在运行时确定泛型时才会出现问题,因为运行时不知道泛型。一个例子是:

\n
List<?> x = new LinkedList<Integer>();\n// this does not compile because the runtime will need to check if the "?" is String, which it can\'t.\nif (x instanceof ArrayList<String>) {\n    System.out.println("Ok");\n}\n
Run Code Online (Sandbox Code Playgroud)\n

根据规范,类型需要与表达式“向下兼容”:

\n
\n

RelationalExpression 必须与 ReferenceType ( \xc2\xa75.5 ) 向下兼容,否则会出现编译时错误。

\n
\n

这意味着:

\n
\n

如果表达式可以通过强制转换而不是未经检查的缩小引用转换来转换为引用类型,则我们说该表达式(或其值)与引用类型向下兼容。

\n
\n

因此,经验法则是,如果(T)foo给您一个未经检查的警告,则意味着foo instanceof T无法编译。

\n

请注意,规范并不总是这么说。Java 8 规范说:

\n
\n

如果 instanceof 运算符后面提到的 ReferenceType 不表示可具体化的引用类型 ( \xc2\xa74.7 ),则这是一个编译时错误。

\n
\n

instanceof WeakReference<String>这在所有情况下都会无效。

\n