Как проверить типы ключа и значения, если объект instanceof HashMap?
у меня есть метод, который принимает объект. В одном случае использования метод принимает HashMap<String, String>
и устанавливает для каждого значения свойство соответствующего имени ключа.
public void addHelper(Object object) {
if (object instanceof HashMap) {
HashMap<String, String> hashMap = (HashMap<String, String>) object;
this.foo = hashMap.get("foo");
this.bar = hashMap.get("bar");
}
}
этот класс придерживается определенного интерфейса, поэтому добавление сеттеров для этих свойств не является опцией.
мой вопрос в том, как я могу проверить тип здесь?
HashMap<String, String> hashMap = (HashMap<String, String>) object;
спасибо заранее!
решение
Спасибо за ответ @drobert, вот мой обновленный код:
public void addHelper(Object object) {
if (object instanceof Map) {
Map map = (Map) object;
if (map.containsKey("foo")) this.foo = map.get("foo").toString();
if (map.containsKey("bar")) this.bar = map.get("bar").toString();
}
}
4 ответов
ты не можешь. Из-за стирания типа отражение покажет, что у вас есть экземпляр HashMap, но типы удаляются во время выполнения. Фактически, у вас есть HashMap.
тем не менее, у вас все еще есть некоторые варианты и некоторые советы, которые я предлагаю вам принять. Среди них:
- проверьте, является ли это экземпляром "карты", а не "HashMap". Это сделает ваш API гораздо более гибким, так как вы, скорее всего, только заботитесь о том, что у вас есть быстрый доступ по ключу чем какое-либо конкретное бесчинство
- воспользуйтесь java.утиль.Api карты, который определяет "containsKey(Object)" и " get (Object)", поэтому вы все еще можете использовать mapInst.получить ("stringKey") безопасно, даже без необходимости бросать.
- вы не можете гарантировать, что все значения являются строками, но вы можете воспользоваться Ява.ленг.Метод toString () объекта и получить строку для каждого значения независимо.
короче говоря: рассматривайте это как любую карту и попытайтесь получить доступ к ключам как Строки даже без приведения и пытаются использовать каждое значение как строку, выполняя проверку null, а затем вызывая .toString (), и у вас будет гораздо более безопасная реализация.
следует отметить, что исходная процедура в точности эквивалентна кодированию
public void addHelper(Object object) {
if (object instanceof HashMap) {
HashMap hashMap = (HashMap) object;
this.foo = (String)(hashMap.get("foo"));
this.bar = (String)(hashMap.get("bar"));
}
}
явно (HashMap)
cast не может вызвать ошибку, так как она защищена instanceof
. Неявно поставляемое (String)
приведения будут вызывать ошибку, только если значения, возвращаемые из HashMap, не являются строками (или нулями).
(под "точно эквивалентным" я имею в виду, что создается тот же байт-код.)
вы должны использовать try-catch, где вы вызываете addHelper(Object)
метод. Это обеспечит ваш правильный тип HashMap
.
try{
addHelper(hashMap);
}
catch(ClassCastException ex){
System.out.println("Is not desired hashmap");
}
try{
HashMap<String, String> hashMap = (HashMap<String, String>) object;
this.foo = hashMap.get("foo");
this.bar = hashMap.get("bar");
}catch(ClassCastException e){
System.err.log("Object is not a hashmap");
}
теперь вы знаете, что объект имеет правильный тип-даже пользовательский абстрактный класс или иначе.