Why using diamond operator when instanting generic Outer class (together with Inner class) gives error in Snippet 2, while snippet 1 is perfectly fine ?
I know that rare types are prohibited, but my case is not rare types - in rare types both Outer and Inner are generic, but one of them (either one) is used as raw, and the other as generic.
Snippet 1:
class Outer {
class Inner<T> {
}
}
class Driver {
public static void main(String[] args) {
Outer.Inner obj1 = new Outer().new Inner<>(); // fine !
Outer.Inner<String> obj2 = new Outer().new Inner<>(); // fine !
}
}
Snippet 2:
class Outer<T> {
class Inner {
}
}
class Driver {
public static void main(String[] args) {
Outer.Inner obj1 = new Outer<>().new Inner(); // fine !
Outer<String>.Inner obj2 = new Outer<>().new Inner(); // error !
}
}
P.S. Tested on Eclipse compiler.
You are trying to use the diamond operator to infer the type parameter:
Outer<String>.Inner obj2 = new Outer<>().new Inner(); // error !
The JLS, section 15.9, says this about diamonds:
A class instance creation expression specifies a class to be instantiated, possibly followed by type arguments (§4.5.1) or a diamond (<>) if the class being instantiated is generic
You have two class instantiation expressions:
new Outer<>()
and
new Inner() // or more precisely, new Outer<>().new Inner()
Towards the end of section 15.9, it distinguishes between these two expressions:
A class instance creation expression is a poly expression (§15.2) if it uses the diamond form for type arguments to the class, and it appears in an assignment context or an invocation context (§5.2, §5.3). Otherwise, it is a standalone expression.
Thus, the second expression is a poly expression, which means that its type depends on the assignment context; but the first expression, new Outer<>()
, is a standalone expression: its type is evaluated free from any context.
Your other statement
Outer.Inner obj2 = new Outer<>().new Inner();
is fine because you are using Outer
as a raw type.