Reputation: 17008
Suppose below class
(without any errors or even warnings):
class C<T> {
C(C1<T> c1) { /*...*/ }
class C1<U> { /*...*/ }
}
Now, how can I make a new instance of it?
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>'
Although the third way doesn't include an error, that isn't what I want! I want new C1<String>
. Also, it includes a warning.
Note that the problem is only when C1
is an inner class
(not static
) of C
. For example, there is no problem with below code:
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)
Upvotes: 1
Views: 75
Reputation: 4882
As @GhostCat explained, you can never instatiate a non-static inner without providing an instance of the outer. And the type T scope is visible to inner class, you don't need to define another type U. I would write it this way:
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;
}
}
Upvotes: 0
Reputation: 140457
You already nailed it.
When you have an inner class that is not static then you always need an instance of the outer, enclosing class in order to create an inner class object (see here for example).
In that sense, you have a chicken/egg problem here, that simply can't be solved. You need an instance of the inner class to create an outer object, but you would first need that outer object to create an inner object.
And even if there would be some dirty hack to work around this, that would most likely be a dirty hack. Simply don't do that. So the real answer here is to step back and have a closer look at the problem that you actually want to solve using this design. To then find a solution that isn't by broken by design.
Upvotes: 1