Mir-Ismaili
Mir-Ismaili

Reputation: 17008

The constructor gets an instance of inner generic class as its parameter. How to use it?

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

Answers (2)

Amith Kumar
Amith Kumar

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

GhostCat
GhostCat

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

Related Questions