It is a compile-time error to pass type arguments to a non-static member class or interface of a raw type that is not inherited from its superclasses or superinterfaces.
I can't think of when this sentence should be used. I have conceived a piece of code by myself:
class OuterGenericClass<T> {
class InnerGenericClass<U> {}
}
public class Main {
public static void main(String[] args)
OuterGenericClass outer = new OuterGenericClass(); //The raw type OuterGenericClass is used
OuterGenericClass<String>.InnerGenericClass<Integer> inner = outer.new InnerGenericClass<Integer>(); //error
}
}
I don't think I passed a type argument to the inner class. I just added a type argument to its constructor. So later I thought my example should not be explained by this sentence.
Then, what situation does this sentence illustrate? Could you give me an example? Thank you for your reading.
This rule prohibits “half-parameterized types” while still permitting raw types. Raw types are generic types with no type parameters provided. They are provided as a legacy feature and shouldn’t be used in new code. (Do note that due to type erasure, code that uses raw types typically compiles to the same as code using parametrized types).
The following statements from JLS 4.8 are appropriate:
The use of raw types is allowed only as a concession to compatibility of legacy code. The use of raw types in code written after the introduction of generics into the Java programming language is strongly discouraged.
and
There is no practical justification for this half-baked [half-parameterized] type. In legacy code, no type arguments are used. In non-legacy code, we should use the generic types correctly and pass all the required type arguments.
An example of the situation described in your quote is given in the box a few paragraphs up. Given the following class declaration:
class Outer<T>{
class Inner<S> {
S s;
}
}
The following declaration is illegal according to the rule you’ve quoted:
Outer.Inner<Double> w; // illegal
Here, Outer is used as a raw type, as it is not given any type parameters. Thus, Outer.Inner is a “non-static member class of a raw type that is not inherited from its superclass”. Therefore, passing type arguments to it is illegal.
The following forms are legal:
Outer.Inner x; // ok, fully raw (legacy)
Outer<Integer>.Inner<Double> y; // ok
The following form is also illegal as it mixes raw and parameterized types in a different way, and is banned by the paragraph after the one you’ve quoted ("It is a compile-time error to attempt to use a member class or interface of a parameterized type as a raw type."):
Outer<Integer>.Inner z; // illegal