У меня есть класс с различными конструкторами:Java дженериков: Как определить точный метод подписи
public class SomeClass {
public SomeClass(Object obj) {
Log.d("x", "SomeClass(Object)");
}
public SomeClass(Integer num) {
Log.d("x", "SomeClass(Integer)");
}
public SomeClass(String str) {
Log.d("x", "SomeClass(String)");
}
public <K, V> SomeClass(Map<K, V> map) {
Log.d("x", "SomeClass(List)");
for (K key : map.keySet()) {
new SomeClass(key);
new SomeClass(map.get(key));
}
}
}
... и некоторый код, который использует его следующим образом:
HashMap<String, Integer> map = new HashMap<>();
map.put("key", 100);
new SomeClass(map);
В результате у меня есть такой вывод:
"SomeClass(List)"
"SomeClass(Object)"
"SomeClass(Object)"
вместо необходимости
"SomeClass(List)"
"SomeClass(String)"
"SomeClass(Integer)"
Я полагаю, что из-за Java Type Erasure вложенные вызовы конструкторов SomeClass попадают в самый общий.
Вопрос: любые идеи, как преодолеть это поведение Java и заставить его вызвать конструктор с требуемым типом параметра? (Статические обертки и шаблон ткани здесь не принимаются)
Вы только с помощью этого класса с 'Map' или также отображает с другими типами? –
Помимо проверки типа ключа и значения с помощью instanceof, я не вижу никакого * принятого * способа. Я думаю, что дизайн должен быть изменен, но вы, кажется, отклоняете этот параметр, поэтому ... Например, я не понимаю, как сделать параметризацию конструктора. Вы можете использовать карту , ?>. –
Java использует статический тип для разрешения метода, в случае дженериков это стирание здесь «Объект». Помимо ручного литья по назначению или с использованием рефлекса ваши варианты с конструкторами ограничены. Вы можете изменить подпись конструктора на 'SomeClass (Map map)'. Но более общее решение - исправить ваш дизайн. –