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-
staticmember 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