How to use generic with type parameter and wildcards together?

You cannot create generic instance with "T". Try using the "?

Up vote 1 down vote favorite share g+ share fb share tw.

Here is some code which does not compile. I would like to hold arbitrary pairs of Class (key) and Map> (values) inside the typeMap; From other methods I want to use one of the value maps with a concrete type, but the algorithms should be generic. I wrote the getIdentityMap() method to deliver a map with a concrete but generic type.

How must I modify the code to compile while being generic? Thanks in advance. Private final Map, Map>> typeMap = new HashMap, Map>(); private Map> getIdentityMap(Class type) { Map> identityMap = typeMap.

Get(type); if (identityMap == null) { identityMap = new HashMap>(); typeMap. Put(type, identityMap); } return identityMap; } EDIT: Here are the compiler errors: In line: Map> identityMap = typeMap. Get(type); compiler error: Type mismatch: cannot convert from Map> to Map> In line: typeMap.

Put(type, identityMap); compiler error: The method put(Class, Map>) in the type Map,Map>> is not applicable for the arguments (Class, Map>) EDIT: edited the generic types of the map attribute to? Java generics map wildcard link|improve this question edited Jul 16 '11 at 14:47 asked Jul 16 '11 at 12:01anonymous383.

Please don't use , but just instead. It's confusing to read when you don't respect the convention. – toto2 Jul 16 '11 at 12:45 Please also include compilation errors.

– toto2 Jul 16 '11 at 12:48 The basic problem is that you cannot instantiate a generics class with a type variable: new Something(); is impossible. This is due to the way generics are implemented in Java (erasure). For a workaround see this post.

There are probably better posts closer to your problem, but I have to run now... – toto2 Jul 16 '11 at 13:05 @toto: Why is new Something impossible? List t = new ArrayList() is very much capable of compiling. Of course if you say new T() then yes, that's impossible.

– Sanjay T. Sharma 2 Jul7 at 14:04 @Sanjay thanks. Quite tricky: new ArrayList() is invalid, but new ArrayList>() is permissible.

– toto2 Jul 17 '11 at 16:48.

You cannot create generic instance with "T". Try using the "? " private final Map, Map>> typeMap = new HashMap, Map>>(); private Map> getIdentityMap(Class type) { Map> identityMap = typeMap.

Get(type); if (identityMap == null) { identityMap = new HashMap>(); typeMap. Put(type, identityMap); } return identityMap; } As mentioned in the comments, this is because of Java erasure to maintain compatibility with older classes which did not use generics. The compiler removes the type information from parameters and arguments.

– Sanjay T. Sharma Jul 16 '11 at 14:05 @Sanjay T. Sharma the question was primarily how to remove compilation errors, so I just assumed, rest of the stuff would be taken care by the developer.

But I see that you have included everything, so leaving my answer as is. – kensen john Jul 16 '11 at 14:10.

You can do it if you are willing to re-design a bit and are OK with a single unchecked cast (which should never fail IMO). Public class TmpTest { public static void main(final String args) { ClassDescriptorMap m = new ClassDescriptorMap(); LongDescriptorMap identityMap = m. GetIdentityMap(String.

Class); identityMap. Put(1L, Arrays. AsList("hi")); System.out.

Println(identityMap); identityMap = m. GetIdentityMap(String. Class); identityMap.

Put(2L, Arrays. AsList("hello")); System.out. Println(identityMap); LongDescriptorMap identityMap2 = m.

GetIdentityMap(Object. Class); System.out. Println(identityMap2); } } class ClassDescriptorMap { private final Map, LongDescriptorMap> typeMap = new HashMap, LongDescriptorMap>(); public LongDescriptorMap getIdentityMap(Class type) { @SuppressWarnings("unchecked") LongDescriptorMap identityMap = LongDescriptorMap.class.

Cast(typeMap. Get(type)); if (identityMap == null) { identityMap = new LongDescriptorMap(); typeMap. Put(type, identityMap); } return identityMap; } @Override public String toString() { return typeMap.toString(); } } class LongDescriptorMap { private Map> map = new HashMap>(); public List get(Object key) { return map.

Get(key); } public List put(Long key, List value) { return map. Put(key, value); } @Override public String toString() { return map.toString(); } }.

Thx for your work, but this isn't what I am looking for. This solutions seems to be doing something different. – anonymous Jul 16 '11 at 14:52 @anonymous: Of course, this was an example; just replace List with ObjectDescriptor in LongDescriptorMap and you should be good to go, no?

– Sanjay T. Sharma Jul 16 '11 at 15:01 OK, the most important thing you did is: MyClass.class.cast(). Now I did: Map> identityMap = Map.class.

Cast(typeMap. Get(type)); and the other way round. Seems to work at the first look.

I have to test it more completely. I just don't understand why a simple cast does not compile? Is this realy because of type erasure?

– anonymous Jul 16 '11 at 15:38 Well, it doesn't compile because you don't cast it and the compiler has no way of knowing for sure that the conversion you are performing would fail at runtime or not. – Sanjay T. Sharma Jul 16 '11 at 16:11.

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions