It is a reply for the affirmation of the answer for "What is a raw type and why shouldn't we use it?", that say:
... In summary, raw types should NEVER be used in new code. You should always use parameterized types. ...
I didn't agree yet, that "you should NEVER use raw type". I think there are cases that you can use it safely.
For me there are three kind of raw type:
"raw type": A raw instance of every class that have this assignment: class Foo <T>
. Ex: Foo foo = new Foo()
"raw type with extends": A raw instance of every class that have this assingment: class Foo <T extends SomeClass>
. Ex: Foo foo = new Foo()
"raw type with extends multi bounds": A raw instance of every class that have this assingment: class Foo <T extends SomeClass & SomeInterface1 & SomeInterface2>
. Ex: Foo foo = new Foo()
The second one is the class that I think could be used safely (class Foo <T extends SomeClass>
). And I would like to know if someone see any problem about it.
Example:
public class Tests {
public static void main(String... args){
GenericClass<SomeClassWithSomeInterface> genericClass1 = new GenericClass<>();
genericClass1.set(new SomeClassWithSomeInterface());
genericClass1.set(new SomeExtendClass());
genericClass1.set(new Object()); // Compile-time error: type is safe
GenericClass genericClass2 = new GenericClass<>();
genericClass2.set(new SomeClassWithSomeInterface());
genericClass2.set(new SomeExtendClass());
genericClass2.set(new Object()); // Compile-time error: type is safe too. Or not?
}
}
class SomeClass{
}
interface SomeInterface{
}
class SomeClassWithSomeInterface extends SomeClass implements SomeInterface{
}
class GenericClass<T extends SomeClassWithSomeInterface>{
private T t;
public void set(T t){
this.t = t;
}
}
class SomeExtendClass extends SomeClassWithSomeInterface{
}
In this example above, both genericClass1 object and genericClass2 are type safe. My understanding is correct?
Consider this:
class SomeExtendingClass extends SomeClassWithSomeInterface {}
class SomeOtherExtendingClass extends SomeClassWithSomeInterface {}
class Test {
public static void main() {
GenericClass<SomeExtendingClass> generic1 = new GenericClass<SomeExtendingClass>();
generic1.set(new SomeExtendingClass()); // ok
generic1.set(new SomeOtherExtendingClass()); // error (as expected)
GenericClass generic2 = new GenericClass<SomeExtendingClass>();
generic2.set(new SomeExtendingClass()); // ok
generic2.set(new SomeOtherExtendingClass()); // ok (but shouldn't be!)
}
}