Unexpected result combining generics and superclasses
Java 1.5
Consider the following code snippet where class B extends class A
Map <String, A> baseMap = new HashMap<String, A>(),
assignMap = null;
Map <String, B> derivedMap = new HashMap<String, B>();
I expected I could do the following:
assignMap = derivedMap;
because A is superclass of B, instead I get a compiler error.
Is it by design ?
I cannot see any reason it shouldn't work. According to me it is safe,
isn't it ?
Thank you
Filippo
# 1
It is by design, because it's not safe.
If you could do what you suggested, then you be able to do:
baseMap.put("An A", new A());
then...
derivedMap.get("An A");
and you'd get an A out of a map which claims to only hold Bs.
# 2
Oh - it wasn't clear what assignMap was, so I ignored it! :-)
# 3
assignMap is the same type as baseMap, that is a Map <String, A>I cannot understand why I cannot assign it a Map<String, B> where B is a specialization of superclass A.Thank youFilippo
# 4
Ok I have found this in the faq.
http://www.angelikalanger.com/GenericsFAQ/FAQSections/ParameterizedTypes.html#Are%20different%20concrete%20instantiations%20of%20the%20same%20parameterized%20type%20compatible?
Now the rule is clear to me, but not the reasons that stay behind the rule.
Thank you
Filippo
# 5
I already explained this to you.
# 6
I have a similar problem:
I have a Class , lets call it A, and another 2 Classes That extends Class A , lets call them: A1, A2.
i also have "VendorContact" and "CustomerContact" that extends class "Contact"
In Class A i Defined:
public ArrayList<? extends Contact> contactsLst;
And in It's Derived classes i Defined:
setContactsLst( new ArrayList<VendorContact>());
setContactsLst( new ArrayList<CustomerContact>());
When I try to add new item (that extends A) to the list like that:
contactsLst.add(newCnt);
I get an error message: cannot find Symbol....
shoul I define an AraayList in each derived class? I think there is a better solution.
Can you help me?
# 7
> I already explained this to you.
No dannyyates, you didn't.
I'm not interested in this:
>>baseMap.put("An A", new A());
>>then...
>>derivedMap.get("An A");
I'm interested in exactly the opposite:
derivedMap.put("A B instance", new B());
baseMap = derivedMap; // compiler error
class A instance = baseMap.get("A B instance");
baseMap is a Map with key of type String and values of type A
Every B instance is also an A instance !
Bye
# 8
It's exactly the same problem.If you could do what you just said, then you could put an A into the map through the baseMap reference, and then retrieve it through the derivedMap instance, and that would break type-safety.
# 9
> I'm interested in exactly the opposite:
>
> derivedMap.put("A B instance", new B());
> baseMap = derivedMap; // compiler error
> class A instance = baseMap.get("A B instance");
If you define baseMap as Map<? extends A> it will work. You won't be able to put anything into the baseMap, avoiding the issue dannyyates described.