假设低于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>
。此外,它还包含警告。
请注意,问题仅在C1
是class
的内部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)
答案 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;
}
}