Joker
Joker

Reputation: 11156

Compilation fails for Generic class with Generic Interface

To my understanding following code should run without any compilation error.

However, when I run this program I am getting following compilation error.

The member type B.D cannot be qualified with a parameterized type, since it is static. Remove arguments from qualifying type B

class B<X> {
    interface C {
    }

    interface D<Y> {
    }
}

class Test {
     // compilation fails here
    B<String>.D<String>[] arr = new B<String>.D<String>[10];
}

Please help me understand this behavior.

Upvotes: 3

Views: 671

Answers (3)

GhostCat
GhostCat

Reputation: 140457

First of all, you can not create arrays of concrete parametrized types. Example:

Pair<Integer,Integer>[] intPairArr = new Pair<Integer,Integer>[10]; // illegal 

does not work. See here for details.

But it looks like the compiler is giving you a different, less helpful error message here because it first stumbles over the fact that nested interfaces are similar to static inner classes.

So, the only thing that you can do is: ignore the generic type on the rhs of the assignment:

B.D<String>[] arr = new B.D[10];

which of course leads to type safety warnings - and makes the whole idea of having that inner interface being generic somehow obsolete.

So the real answer is probably: generics and arrays do not go well together in Java - avoid using them in the first place. And don't be surprised that making things more complicated by bringing in interface nesting results in even less of "nice user experience".

Upvotes: 2

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726599

In a way similar to an inner static class, a nested interface does not have an association to an instance of its outer class, only to the class itself. All static members are shared among all instances of B, regardless of B's type parameter. Consider:

class B<T> {
    public static int shared = 0;
}

Variable shared is the same in B<String>, B<Integer>, B<Object> and so on. An attempt to access it on a parameterized B leads to a compile error:

int copy = B<String>.shared; // <<== Does not compile

Hence, type parameter of B has no effect on the declaration of arr, so Java wants you to remove it:

B.D<String>[] arr = new B.D[10];

Upvotes: 4

Zefick
Zefick

Reputation: 2119

Inner interfaces are always static (unlike classes). So parameter String for B make no sense in definition new B<String>.D<String>.

Upvotes: 1

Related Questions