首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用本地类时出现错误“instanceof的泛型类型非法”

使用本地类时出现错误“instanceof的泛型类型非法”
EN

Stack Overflow用户
提问于 2019-04-16 16:35:38
回答 4查看 2.9K关注 0票数 63

我有以下使用本地类的Java代码。

代码语言:javascript
复制
import java.util.Arrays;

public class X<T> {
    void m() {
        class Z {}

        for (Object o : Arrays.asList(1, 2, 3))
            if (o instanceof Z) {}
    }
}

它不能编译,并显示以下错误消息:

代码语言:javascript
复制
X.java:8: error: illegal generic type for instanceof
            if (o instanceof Z) {}
                             ^
1 error

我知道本地类Z继承了X<T>的泛型类型签名,它是一个内部类。同样的编译错误出现在此示例中,其中Z不是本地的,但仍然是内部的:

代码语言:javascript
复制
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设为非内部/静态来解决:

代码语言:javascript
复制
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提供

代码语言:javascript
复制
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
        }
    }
}

但是,如何才能在不更改本地类本身的情况下限定本地类或解决此限制呢?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2019-04-16 16:57:14

对我来说,这似乎是Java语言中的一个疏忽或限制,我认为这是不可能的。

根据JLS 4.7instanceof表达式中引用的类型必须是可重用的,这意味着它必须通过其完全限定名表示为可重用类型。同时,JLS 6.7指出,本地类没有完全限定的名称,因此它们不能表示为reifiable。

如果将Z声明为泛型,则instanceof运算符会将Z视为原始类型,其中它的所有泛型属性-在本例中为封闭类-也被视为原始类型。(类似于raw类型的泛型方法被视为raw,而不考虑任何泛型签名。这是一种保持类型泛化的向后兼容性的措施。)因为任何原始类型都是可重用的,所以将Z声明为泛型将被编译。

票数 43
EN

Stack Overflow用户

发布于 2019-04-16 16:35:38

一种可能的解决方法是使用反射:

代码语言:javascript
复制
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)) {}
    }
}
票数 28
EN

Stack Overflow用户

发布于 2019-04-16 16:42:40

显然,通过使Z泛型编译成功。我本以为需要<T>作为类型参数,但您只需将其泛型,所以任何东西都可以

代码语言:javascript
复制
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)) {}
    }
}

正确的解决方案是限定本地类,但我不认为您可以这样做。要么将其重构为私有静态类,要么这可能是您能得到的最好的。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55703849

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档