构造函数获取内部泛型类的实例作为其参数。如何使用它?

时间:2018-05-25 19:53:49

标签: java generics instantiation inner-classes

假设低于class(没有任何错误甚至警告):

class C<T> {
    C(C1<T> c1) { /*...*/ }

    class C1<U> { /*...*/ }
}

现在,我该如何制作新的实例?

new C<String>(new C1<String>()) {};  // Error behind `<String>`: Type arguments given on a raw type 
                                     // + Warning behind `new C1<String>()`: Unchecked assignment: 'com.example.package.C.C1<java.lang.String>' to 'com.example.package.C<java.lang.String>.C1<java.lang.String>'type

new C<String>(new C1<>()) {};        // Error behind `<>`: Type arguments given on a raw type

new C<String>(new C1()) {};          // Warning behind `new C1()`: Unchecked assignment: 'com.example.package.C.C1' to 'com.example.package.C<java.lang.String>.C1<java.lang.String>'

虽然第三种方式不包含错误,但这不是我想要的! 我想要new C1<String> 。此外,它还包含警告。

请注意,问题仅在C1class的内部static(不是C)时。例如,下面的代码没有问题:

class C<T> {
    C(C2<T> c1) { /*...*/ }

    //class C1<U> { /*...*/ }
}

class C2<V> { /*...*/ }

...

new C<String>(new C2<String>()) {};  // OK
new C<String>(new C2<>()) {};        // OK (and is equivalent)

2 个答案:

答案 0 :(得分:1)

你已经钉了它。

如果内部静态,那么始终需要外部封闭类的实例才能创建内部类对象(例如,参见here)。

从这个意义上讲,你在这里遇到了鸡/蛋问题,根本无法解决。您需要内部类的实例来创建外部对象,但您首先需要该外部对象来创建内部对象。

即使有一些肮脏的黑客来解决这个问题,那很可能是 dirty hack。根本不要这样做。所以这里真正的答案是退一步,仔细看看你实际想要使用这个设计解决的问题。然后找到一个不受设计破坏的解决方案。

答案 1 :(得分:0)

正如@GhostCat所解释的那样,如果不提供外部实例,就永远不能实现非静态内部。并且类型T范围对于内部类是可见的,您不需要定义另一种类型U.我会这样写:

    public class Solve {
       public static void main(String[] args){
            C<String> c = new C<>();
            c.c1 = c.new C1();
            c.c1.value = "Inner Generic Class";
            System.out.println(c.c1.value);
       }
    }


    class C<T> {   

       public C1 c1;

       class C1 {
            public T value;
       }
    }
相关问题