Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is proper way to define Map<String, ?> method parameter

Tags:

java

generics

I have a custom Map to String method. It is meant to be used with any kind of Map that has String keys, not restricted to some specific map value type. The map values might have come from javax.jms.Message.getObjectProperty(String name) method, for example, or just be plain Strings.

Which of following is the most "proper" method signature to use, and why, or are all equal?

String map2String(Map<String, Object> map){...}

or

String map2String(Map<String, ?> map){...}

or

String map2String(Map<String, ? extends Object> map){...}

or (added edit)

<E> String map2String(Map<String, ? extends E> map){...}

or something else?

Also, the method contains for-each loop somewhat like this:

for(Entry<String, ?> entry : map.entrySet()) {
    String key = entry.getKey();
    String value = entry.getValue().toString();
}

Which is "proper" type for the entry variable, does it matter (except the incompatible combination of ? in the map, Object in the entry type).

like image 852
hyde Avatar asked Dec 01 '25 02:12

hyde


2 Answers

String map2String(Map<String, ?> map){...} is correct (? extends Object is redundant)

The first one won't work because you wouldn't be able to call

Map<String,Integer> myMap = {...}
map2String(myMap); // Map<String,Integer>  is not  Map<String,Object>  

The proper type for the entry variable is Entry<String, ?> as you suspected.

like image 192
artbristol Avatar answered Dec 02 '25 17:12

artbristol


The best way is to use 1st example you posted just instead Object use your class type. Otherwise you must cast Object to other class or use instanceof and it's not good idea

 String map2String(Map<String, YourClass> map){...}

About other ones:

String map2String(Map<String, ? extends Object> map){...}

Well, ? extends Object is not the best bet since every Class derived (subtype) from Object. There is no distinction between ? extends Object and ?.

extends wildcard you can use in case if:

class MyClass extends RootClass
....
class YourClass extends RootClass
....
String map2String(Map<String, ? extends RootClass> map)   // this method can fetch argumets by type of Map  `MyClass` and `YourClass`.

further:

String map2String(Map<String, ?> map){...}

Lets say you used String map2String(Map map){...} without any type. Compiler will tell you: Map is a raw type. References to generic type Map should be parameterized. But your too lazy to think about witch parameter to take. So many times I saw, people type like: String map2String(Map<?,?> map){...} to remove Warnings. But its bad approach.

like image 35
Maxim Shoustin Avatar answered Dec 02 '25 17:12

Maxim Shoustin