I wrote the following code:
public class Test<T> {
public void method(){
B b = new B();
}
public class B{ }
}
//Some method in some class contains the following lines
Test<Integer> t = null;
Test.B b = t.new B(); //warning Test.B is a raw type
Why did I get this warning? The declation of the inner type B
doesn't contain type parameter, therefore it's not a generic type. Moreover, the specification gives us the following:
A class is generic if it declares one or more type variables
The class B
doesn't declare the type variables. So why is it a generic type?
Although the inner class B does not declare any type variables, an instance of it implicitly references an instance of the outer class, which does.
Why did I get this warning?
Test<Integer> t = null;
Test.B b = t.new B(); //warning Test.B is a raw type
Because you declared the variable b with a raw type. Instead, you could declare:
Test<Integer>.B b = t.new B(); // no warning!
I agree that the specification of generic classes does not clearly cover your scenario. But the specification of raw types does:
More precisely, a raw type is defined to be one of:
The reference type that is formed by taking the name of a generic type declaration without an accompanying type argument list.
An array type whose element type is a raw type.
A non-
static
member type of a raw type R that is not inherited from a superclass or superinterface of R.
You do not really use the generic type. I will explain it on a slightly more elaborate example:
public class Test<T> {
public B method(T t) {
B b = new B(t);
return (b);
}
public class B {
T value;
public B(T value) {
this.value = value;
}
}
}
Here you can see clearly, that B
depends on the generic parameter T
, without being generic itself. As explained by Andy Thomas, an instance of B
can only be created in co-existence with an instance of Test
. Therefore, B
is (indirectly) generic. In your given example:
Test<Integer> t = null;
Test.B b = t.new B(); //warning Test.B is a raw type
b
does not specify a generic parameter, but t
does. This is, why you get the warning.
The proper way to write this code would be:
Test<Integer> t = null;
Test<Integer>.B b = t.new B();
With this, B
is fully specified and the types match.
Although B is not parameterized, Test.B b = t.new B();
contains a raw reference to Test, which is parameterized. I got the warning to disappear when I changed the warning line to Test<Integer>.B b = t.new B();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With