Luk*_*der 61 java generics local-class
我有以下使用本地类的 Java代码。
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
我了解到,本地类Z继承了的通用类型签名X<T>,即内部类。在此示例中,出现了相同类型的编译错误,该错误Z不是本地的,但仍然是内部的:
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
    }
}
或通过排位赛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
        }
    }
}
但是,如何在不更改本地班级本身的情况下限定本地班级或解决此限制?
Raf*_*ter 43
对我来说,这似乎是Java语言的疏忽或限制,我认为这是不可能的。
instanceof表达式中的引用类型必须根据JLS 4.7是可验证的,这意味着必须通过其完全限定的名称将其表示为可验证的类型。同时,JLS 6.7声明本地类没有完全限定的名称,因此不能将它们表示为可验证的。
如果将Z声明为泛型,则instanceof运算符会将Z其所有泛型属性(在本例中为封闭类)也视为原始类型,并将其视为原始类型。(类似于原始类型的泛型方法,尽管有任何泛型签名也被视为原始类型。这是一种保持类型生成向后兼容的措施。)由于任何原始类型都是可修正的,因此将Z声明为泛型即可编译。
Luk*_*der 28
可能的解决方法是使用反射:
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)) {}
    }
}
显然,通过使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)) {}
    }
}
正确的解决方案将使本地课程合格,但我认为您不能。您可以将其重构为私有静态类,或者可能是最好的。
| 归档时间: | 
 | 
| 查看次数: | 2442 次 | 
| 最近记录: |