Java Reference
In-Depth Information
reason: actual argument List<String> cannot be converted
to List<Object> by method
invocation conversion
1 error
This error message results from being unaware of the fundamental rule of generic
types:
for a given subtype
x
of type
y
, and given
G
as a raw type declaration,
G<x>
is not a subtype of
G<y>
.
Tounderstandthisrule,youmustrefreshyourunderstandingofsubtypepolymorph-
ism(see
Chapter2
).Basically,asubtypeisaspecializedkindofsupertype.Forexample,
Circle
isaspecializedkindof
Shape
and
String
isaspecializedkindof
Object
.
This polymorphic behavior also applies to related parameterized types with the same
type parameters (e.g.,
List<Object>
is a specialized kind of
java.util.Collection<Object>
).
However,thispolymorphicbehaviordoesnotapplytomultipleparameterizedtypes
thatdifferonlyinregardtoonetypeparameterbeingasubtypeofanothertypeparamet-
er. For example,
List<String>
is not a specialized kind of
List<Object>
. The
following example reveals why parameterized types differing only in type parameters
are not polymorphic:
List<String> ls = new ArrayList<>();
List<Object> lo = ls;
lo.add(new Employee());
String s = ls.get(0);
This example will not compile because it violates type safety. If it compiled, a
ClassCastException
would be thrown at runtime because of the implicit cast to
String
on the final line.
Thefirstlineinstantiatesa
List
of
String
andthesecondlineupcastsitsreference
to a
List
of
Object
. The third line adds a new
Employee
object to the
List
of
Object
.Thefourthlineobtainsthe
Employee
objectvia
get()
andattemptstoas-
signittothe
List
of
String
referencevariable.However,
ClassCastException
is thrown because of the implicit cast to
String
—an
Employee
is not a
String
.
Note
Althoughyoucannotupcast
List<String>
to
List<Object>
,youcan
upcast
List<String>
to the raw type
List
in order to interoperate with legacy
code.
Theaforementionederrormessagerevealsthat
List
of
String
isnotalso
List
of