The title is pretty self-explanatory.
Will the raw type of, for example, ArrayList
act the same as ArrayList<Object>
?
Not quite. Take a look at
MyClass myClass1 = new MyClass<Integer>();
//MyClass<Object> myClass2 = new MyClass<Integer>();//compilation error
MyClass<?> myClass3 = new MyClass<Integer>();//this time it compiles
myClass1.setter(1);
//myClass3.setter(1);//compilation error
In case of myClass2
it will not compile because you are declaring reference to holder of Objects
but you are passing holder of Integers
and generics are not covariant
Also if you change <Object>
to <?>
wildcard like in case of myClass3
you wouldn't be able to use its setter with any object (beside null) like myClass3.someSetter(1)
because MyClass<?>
can be reference to MyClass<Anything>
that can hold any type of objects, and passing 1
to holder of Strings
would not be safe.
2 回答
不完全的。看一眼
MyClass myClass1 = new MyClass<Integer>();
//MyClass<Object> myClass2 = new MyClass<Integer>();//compilation error
MyClass<?> myClass3 = new MyClass<Integer>();//this time it compiles
myClass1.setter(1);
//myClass3.setter(1);//compilation error
如果myClass2
它不会编译,因为您声明对持有者的引用Objects
但您正在传递持有者Integers
并且泛型不是协变的
此外,如果您更改<Object>
为<?>
通配符,例如myClass3
您将无法将其设置器与任何对象(除了 null )一起使用,myClass3.someSetter(1)
因为MyClass<?>
可以引用MyClass<Anything>
该对象可以包含任何类型的对象,并且传递1
给持有者Strings
将不安全.
In terms of method signatures, the erased E
is its bound Object
, so it is ok to say that the raw ArrayList
has member methods similar to ArrayList<Object>
In terms of subtyping, raw type is more like wildcard type; ArrayList
is a super type of ArrayList<x>
for any x
. On the other hand, ArrayList<x>
can be converted to raw ArrayList
without raising any compiler error/warning.
This is all for backward compatibility. You should avoid raw types anyway so you don't need to know these useless information.