-4

My intention is to cast a Object to (?) but how to do this? My Code:

Map<T,?> rawResult = initMap;
final T key = ...
final Object kryoResult = kryo.readClassAndObject(input);
rawResult.put(key,value);

Which brings me following error

Wrong 2nd argument type. Found: 'java.lang.Object', required: '?'

Cast doesn't work:

(?)value 

Also this:

final ? value = ...

Isn't ? an Object? Because ? is "whatever... I don't care?"?

Pwnstar
  • 2,333
  • 2
  • 29
  • 52

2 Answers2

1

Because ? is "whatever... I don't care?"

That's wrong: ? is I don't know rather than I don't care. That's why you can not add something to the map. because the map could also hold String objects. So adding an Object would cause an error.

Map<T, String> stringMap = new HashMap<>();
stringMap.put(key, "Value");
Map<T, ?> map =  stringMap; // works
Object value = map.get(key); // Object, because "map" doesn't know the types its holding
map.put(key, "New Value"); // doesn't work, even though the map is holding stringValues

Also have a look at this question which explains wildcards ? in more detail.

Andy Turner
  • 137,514
  • 11
  • 162
  • 243
Lino
  • 19,604
  • 6
  • 47
  • 65
-1

In this case where you declared to accept ?(unknown type) and trying to insert Object(known type), the compiler is not able to confirm the type of object that is being inserted into the list, and an error is produced.

To get rid of such error we need to use a helper method so that the wildcard can be captured through type inference.

Map<T, ?> map = new HashMap<>();
T key = ...;
Object value = ...;
putInMap(map, key, value);

and method for putting value in map:

@SuppressWarnings("unchecked")
<K, V> void putInMap(Map<K, V> map, K key, Object value) {
    map.put(key, (V) value);
}

Basically, ?(unknown type) is used when you want to iterate through the collection or Map with upper bounded type(Object in case not bounded).

You might want to go through the documentation here https://docs.oracle.com/javase/tutorial/java/generics/wildcardGuidelines.html.

Hope this help. Enjoy :)

  • 1
    "To get rid of such error" You're not getting rid of the error, you're just changing a compile-time error into a runtime error. The compiler is telling you that you're doing something it can't prove to be safe; doing this - effectively saying "hush, you, I know what I'm doing" - is just asking for trouble. What's particularly insidious here is that the failure won't occur in this code, but instead later, when you try to get a *whatever* out of the map - and it will be a total nightmare to work out where that value came from. – Andy Turner Dec 18 '17 at 09:53
  • Agree. Thanks @Andy for correcting it. It should be like "To get rid of such error at compile time". – Neetesh Bhardwaj Dec 18 '17 at 10:00
  • 1
    But you're still missing my point: an error at compile time is vastly preferable to an error at runtime, so don't change the former to the latter blindly. – Andy Turner Dec 18 '17 at 10:01
  • Yeah. Generally, we should not do this. But there are times where we need to handle such situations, how we should deal with them. I would feel great if you could help me to improve the answer. – Neetesh Bhardwaj Dec 18 '17 at 10:30