是否可以使用参数化通用内部类?

时间:2014-10-19 14:16:12

标签: java generics inner-classes

package generics;
public class InnerClassGenerics{
     class Innerclasss{

    }
    public static void main(String[] args) {
        InnerClassGenerics icg=new InnerClassGenerics();
        Innerclasss innerclass=icg.new Innerclasss();
    }
}

以上代码是可能的并且编译得很好!!!


为什么以下代码无法编译,是否可以参数化内部类?

package generics;
public class InnerClassGenerics<T>{
    class Innerclasss<T>{

    }
    public static void main(String[] args) {
        InnerClassGenerics<String> icg=new InnerClassGenerics<>();
        Innerclasss<String> innerclass=new Innerclasss<>();
    }
}

在上面的代码中,如果该类是静态的,它可以正常工作! 为什么没有静态关键字是不可能的?

2 个答案:

答案 0 :(得分:3)

通常情况下,如果外部类不存在任何泛型类型,则可以编写如下代码:

Outer outer = new Outer();
Inner inner = outer.new Inner();

因为内部类中的每个方法都已经知道它应该使用什么类型。

但是当外部类使用泛型类型时,情况稍微复杂一些。由于内部类可以访问其外部类(或类)的所有成员,因此还需要了解外部类中使用的泛型类型,以确保操作泛型值时的类型安全。

看看这段代码:

class Outer<T> {
    private T someValue;

    class Inner {
        T getOuterValue(){
            return someValue;
        }
        void setOuterValue(T value){
            someValue=value;
        }
    }
    //rest of code
}

这意味着Inner类的实例也依赖于其外部类的泛型类型。这就是为什么在创建对内部类的引用时,需要通过将其写为

来显式地使用具有泛型类型的外部类
Outer<String> outer = new Outer<>();
Outer<String>.Inner inner = outer.new Inner();
^^^^^^^^^^^^^

或明确地说外部类使用raw type(不鼓励),如

Outer.Inner inner = outer.new Inner();

因此,要使代码正常工作,您需要:

  1. 添加外部类类型(最好使用其泛型类型)

  2. 在外部类的实例上调用内部类的构造函数(就像在没有实例的情况下可以调用非静态方法一样,必须使用外部类实例创建非静态(内部)类)

    InnerClassGenerics<String>.Innerclasss<String> innerclass = icg.new Innerclasss<>();
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^                                 ^^^^
             point 1                                           point 2
    
  3. 此外 不应该为嵌套类及其外部类中的泛型类型指定相同的名称 ,就像在这种情况下一样

    public class InnerClassGenerics<T>{
        class Innerclasss<T>{
            ...
        }
    }
    

    因为来自T Innerclasss隐藏 T来自其外部类InnerClassGenerics(不是它会导致当前问题,但它可以使您的生活困难以后)。

答案 1 :(得分:-1)

所以你有这个类定义,它不会编译,因为你有2个类型叫T。使它像这样,它将编译:

public class OuterClass <O>
{
    public class InnerClass <I>
    {
    }
}

另外,请注意您正在从静态方法实例化非静态类。您完成的代码应如下所示:

public class OuterClass <O>
{
    public static class InnerClass <I>
    {
    }

    public OuterClass ()
    {
    }
    public InnerClass<O> getInnerClass ()
    {
        return new InnerClass<O>();
    }

    public static void main (String[] args)
    {
        OuterClass<String> outer = new OuterClass<>();
        InnerClass<String> inner = outer.getInnerClass();
    }
}

上面的代码需要Java 8才能编译。