使用本地 类 时出错 "illegal generic type for instanceof"
Error "illegal generic type for instanceof" when using local classes
我有以下 Java 使用 local class.
的代码
import java.util.Arrays;
public class X<T> {
void m() {
class Z {}
for (Object o : Arrays.asList(1, 2, 3))
if (o instanceof Z) {}
}
}
它没有编译并出现以下错误消息:
X.java:8: error: illegal generic type for instanceof
if (o instanceof Z) {}
^
1 error
我了解到本地 class Z
继承了 X<T>
的通用类型签名,是一个内部 class。同样的编译错误出现在这个例子中,其中 Z
不是本地的,但仍然是 inner:
import java.util.Arrays;
public class X<T> {
class Z {}
void m() {
for (Object o : Arrays.asList(1, 2, 3))
if (o instanceof Z) {} // Compilation error
}
}
可以通过使 Z
非内部/静态来解决:
import java.util.Arrays;
public class X<T> {
static class Z {}
void m() {
for (Object o : Arrays.asList(1, 2, 3))
if (o instanceof Z) {} // Compiles now
}
}
或通过qualifying X.Z
:
import java.util.Arrays;
public class X<T> {
class Z {}
void m() {
for (Object o : Arrays.asList(1, 2, 3)) {
if (o instanceof X.Z) {} // Compiles now
if (o instanceof X<?>.Z) {} // Also
}
}
}
但是我如何才能限定本地 class,或者在不更改本地 class 本身的情况下解决此限制?
一种可能的解决方法是使用反射:
import java.util.Arrays;
public class X<T> {
void m() {
class Z {}
for (Object o : Arrays.asList(1, 2, 3))
if (Z.class.isInstance(o)) {}
}
}
这也应该有效。也使用反射。但似乎是一个有效的解决方案。
import java.util.Arrays;
public class X<T> {
void m() {
class Z2 {
}
for(Object o: Arrays.asList(1,2,3)) {
if(Z2.class.isAssignableFrom(o.getClass())) {
}
}
}
}
显然,通过使 Z 泛型编译成功。我预计需要 <T>
作为类型参数,但你只需要把它变成通用的,所以什么都可以
import java.util.Arrays;
public class X<T> {
void m() {
class Z<Anything> {}
for (Object o : Arrays.asList(1, 2, 3))
if (Z.class.isInstance(o)) {}
}
}
正确的解决方案是限定本地 class,但我认为您做不到。要么将其重构为私有静态 class,要么这可能是您可以获得的最好结果。
对我来说,这似乎是 Java 语言的疏忽或限制,我认为这是不可能的。
根据 JLS 4.7, meaning that it must be expressed as a reifiable type by its fully qualified name. At the same time, JLS 6.7 声明,instanceof
表达式中的引用类型必须是可具体化的,因为本地 classes 没有完全限定的名称,因此它们不能表示为具体化。
如果您将 Z 声明为泛型,则 instanceof
运算符会将 Z
视为原始类型,其中它的所有泛型属性(在本例中为封闭的 class)都被视为原始类型以及。 (类似于原始类型的泛型方法被认为是原始的,尽管有任何泛型签名。这是一种保持类型泛化向后兼容性的措施。)由于任何原始类型都是可具体化的,因此将 Z 声明为泛型将编译。
我有以下 Java 使用 local class.
的代码import java.util.Arrays;
public class X<T> {
void m() {
class Z {}
for (Object o : Arrays.asList(1, 2, 3))
if (o instanceof Z) {}
}
}
它没有编译并出现以下错误消息:
X.java:8: error: illegal generic type for instanceof
if (o instanceof Z) {}
^
1 error
我了解到本地 class Z
继承了 X<T>
的通用类型签名,是一个内部 class。同样的编译错误出现在这个例子中,其中 Z
不是本地的,但仍然是 inner:
import java.util.Arrays;
public class X<T> {
class Z {}
void m() {
for (Object o : Arrays.asList(1, 2, 3))
if (o instanceof Z) {} // Compilation error
}
}
可以通过使 Z
非内部/静态来解决:
import java.util.Arrays;
public class X<T> {
static class Z {}
void m() {
for (Object o : Arrays.asList(1, 2, 3))
if (o instanceof Z) {} // Compiles now
}
}
或通过qualifying X.Z
:
import java.util.Arrays;
public class X<T> {
class Z {}
void m() {
for (Object o : Arrays.asList(1, 2, 3)) {
if (o instanceof X.Z) {} // Compiles now
if (o instanceof X<?>.Z) {} // Also
}
}
}
但是我如何才能限定本地 class,或者在不更改本地 class 本身的情况下解决此限制?
一种可能的解决方法是使用反射:
import java.util.Arrays;
public class X<T> {
void m() {
class Z {}
for (Object o : Arrays.asList(1, 2, 3))
if (Z.class.isInstance(o)) {}
}
}
这也应该有效。也使用反射。但似乎是一个有效的解决方案。
import java.util.Arrays;
public class X<T> {
void m() {
class Z2 {
}
for(Object o: Arrays.asList(1,2,3)) {
if(Z2.class.isAssignableFrom(o.getClass())) {
}
}
}
}
显然,通过使 Z 泛型编译成功。我预计需要 <T>
作为类型参数,但你只需要把它变成通用的,所以什么都可以
import java.util.Arrays;
public class X<T> {
void m() {
class Z<Anything> {}
for (Object o : Arrays.asList(1, 2, 3))
if (Z.class.isInstance(o)) {}
}
}
正确的解决方案是限定本地 class,但我认为您做不到。要么将其重构为私有静态 class,要么这可能是您可以获得的最好结果。
对我来说,这似乎是 Java 语言的疏忽或限制,我认为这是不可能的。
根据 JLS 4.7, meaning that it must be expressed as a reifiable type by its fully qualified name. At the same time, JLS 6.7 声明,instanceof
表达式中的引用类型必须是可具体化的,因为本地 classes 没有完全限定的名称,因此它们不能表示为具体化。
如果您将 Z 声明为泛型,则 instanceof
运算符会将 Z
视为原始类型,其中它的所有泛型属性(在本例中为封闭的 class)都被视为原始类型以及。 (类似于原始类型的泛型方法被认为是原始的,尽管有任何泛型签名。这是一种保持类型泛化向后兼容性的措施。)由于任何原始类型都是可具体化的,因此将 Z 声明为泛型将编译。