Как проверить типы ключа и значения, если объект 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");
    }

теперь вы знаете, что объект имеет правильный тип-даже пользовательский абстрактный класс или иначе.