java - Doubly-Wildcard Generic Type error -
i trying define operator ++
custom map
type this:
@override public mutablemap<k, v> $plus$plus(map<? extends k, ? extends v> map) { hashmap<k, v> copy = this.copy(); map.$plus$plus$eq(map); return copy; }
the ++=
operator defined this:
public void $plus$plus$eq(map<? extends k, ? extends v> map);
however, compiler complains on map.$plus$plus$eq(map);
line, following crazy error:
the method $plus$plus$eq(map<? extends capture#10-of ? extends k, ? extends capture#11-of ? extends v>) in type map<capture#10-of ? extends k,capture#11-of ? extends v> not applicable arguments (map<capture#12-of ? extends k,capture#13-of ? extends v>)
as can see in screenshot, none of solutions provided eclipse work, yet alone make sense:
i have been working java generics quite while now, having developed own generic type system custom programming (whose library trying code), have never had error before.
edit: interestingly, casting map
argument raw type (map)
seems fix problem.
map.$plus$plus$eq((map) map);
however, changing cast (map<?, ?>)
(which eclipse's second solution does) causes similar error.
it works if use raw type map
, lose type safety. don't use raw types. exist compatibility java 1.4 , older, didn't have generics.
it doesn't work wildcards because compiler doesn't know exact types wildcards ?
stand for. reason same question why can't call add()
on list<? extends t>
.
note wildcard not mean can use whatever types of objects type of key extends k
, type of value extends v
. instead, means have map keys of specific, unknown type k
, , values of specific, unknown type v
. can't call $plus$plus$eq
on such map because compiler doesn't know exact types, can't check them.
in principle, wildcards of map
call method on, might stand types different wildcards of map
pass argument - though can see in case must same because use same object map
in case.
you can fix using type parameters instead of wildcards:
@override public <kk extends k, vv extends v> mutablemap<k, v> $plus$plus(map<kk, vv> map) { hashmap<k, v> copy = this.copy(); map.$plus$plus$eq(map); return copy; }
Comments
Post a Comment