【问题标题】:why object of inner class cannot be generated in generics为什么不能在泛型中生成内部类的对象
【发布时间】:2014-06-09 06:50:54
【问题描述】:

我有以下代码

class OuterClass<T>{

class Innerclass{
int k;
}

public static void main(String argv[]){

OuterClass<Integer> out =new OuterClass<>();
Innerclass in; // errors out
}

}

但是对于像下面的代码这样没有泛型的类,我可以为内部类创建对象。

class OuterClass{

class Innerclass{
int k;
}

public static void main(String argv[]){

OuterClass out =new OuterClass();
Innerclass in; // No error

}

}

为什么我无法创建内部类的对象,尽管在我的第一个示例中内部类中没有使用泛型?请解释一下。

【问题讨论】:

  • 请注意,这两个版本的代码实际上都没有创建内部类的实例。您只需声明内部类类型的变量。

标签: java generics inner-classes


【解决方案1】:

您的 main 方法属于 OuterClass 并且在那里是静态的。由于InnerClass 不是静态类,而是隐式依赖于泛型类型T(泛型类型在内部类中可用,即使您的示例没有使用它),您不能从静态方法中引用它。

换句话说,由于InnerClass 依赖于泛型类型,因此您不能将它从OuterClass 中“丢失”并在其外部使用。

如果您的内部类不依赖于泛型类型,您可以将其设为静态。但是,在这种情况下,您可能需要考虑将其提取到单独的类中,而不是嵌套类:

class OuterClass<T> {
    static class InnerClass {
        int k;
    }

    public static void main( String argv[] ) {
        InnerClass inner = new InnerClass();
    }
}

如果泛型对内部类很重要,您可以通过指定它(注意outerinner 的泛型类型必须匹配)或使用@ 来告诉编译器为外部类推断哪个泛型987654330@ 在这种情况下编译器将使用原始类型:

class OuterClass<T> {
    class InnerClass {
        int k;
    }

    public static void main( String argv[] ) {
        OuterClass<String> outer = new OuterClass<String>();

        // works and has the "correct" generic type
        OuterClass<String>.InnerClass inner1 = outer.new InnerClass();

        // works, but uses the raw type
        OuterClass.InnerClass inner2 = outer.new InnerClass();
    }
}

请注意,您需要一个OuterClass&lt;T&gt; 类型的封闭实例outer 才能实例化InnerClass(因为该类不是静态的,它属于OuterClass 的一个实例)。

这也适用于没有泛型的例子:你需要一个封闭的实例来实例化内部类,所以

class OuterClass {
    class InnerClass {
        int k;
    }

    public static void main( String argv[] ) {
        OuterClass outer = new OuterClass();
        InnerClass in = outer.new InnerClass();
    }
}

将工作,而

class OuterClass {
    class InnerClass {
        int k;
    }

    public static void main( String argv[] ) {
        OuterClass outer = new OuterClass();
        InnerClass in = new InnerClass();
    }
}

不会。

【讨论】:

  • 这并不能解释为什么没有泛型的版本可以编译。
  • @user2357112 它只是编译,因为他没有实例化类。即使在没有泛型的版本中,仅仅InnerClass in = new InnerClass() 也会失败,因为没有给出封闭实例。我编辑了我的答案。
  • 新版答案解释更多。我想补充一点,OuterClass.InnerClass inner; 编译 OuterClass 是否是通用的,因为它使用原始类型。 InnerClass inner; 尝试使用参数化类型并且没有提供类型参数。
猜你喜欢
  • 1970-01-01
  • 2017-08-04
  • 1970-01-01
  • 2019-10-20
  • 1970-01-01
  • 2020-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多