HashMap <Integer, String> хранит String [] (Atlassian Confluence)

Итак, я работаю над плагином для Atlassian Confluence, и в моем контроллере для страницы конфигурации у меня есть HashMap типа HashMap<Integer, String>, которую я заполняю значениями из HTML-формы. Теперь, после отправки формы, я пытаюсь прочитать значение из этого HashMap с помощью .get(key) и сохранить его в String. Я получаю эту ошибку приведения типов: java.lang.ClassCastException: [Ljava.lang.String; cannot be cast to java.lang.String. Поэтому я посмотрел на значения с помощью отладчика, и, конечно же, моя HashMap содержит строки, обернутые в массивы длины 1 вместо простых простых строк: даже жесткая моя HashMap четко определена с типами Integer-> String, и присвоение String работает без явного приведение типов. Это меня действительно сбивает с толку. Я предполагаю, что это имеет отношение к материалам Atlassian, автоматически десериализирующим POST-значения; в прошлом это уже стоило мне довольно много головной боли, так как нет надлежащей документации, а волшебное преобразование фона имеет довольно много причуд. Что действительно меня сильно смущает, так это тот факт, что HashMap может внезапно хранить значения другого типа, чем определено, я бы не подумал, что это возможно, если Java уделяет такое внимание безопасности типов. Есть ли какое-то отражение foo, которое может это сделать, о котором я не знаю? Или я неправильно понимаю природу HashMaps? Кто-нибудь когда-нибудь испытывал нечто подобное? У меня нет опыта программирования на Java.

Что действительно меня сильно смущает, так это тот факт, что HashMap может внезапно хранить значения другого типа, чем определено, я бы не подумал, что это возможно, если Java уделяет такое внимание безопасности типов.Тип Стирание.
Elliott Frisch 21.03.2018 12:41

Для тех, кто борется с формами Atlassian xwork / velocity, очевидно, синтаксис field[1] для карт не работает. Возможно, field.1 сработает, точечный синтаксис отлично работает для вложенных объектов (если вы используете @ParameterSafe в своих классах). Массивы работают в виде <input name = "test" value = "A"><input name = "test" value = "B">вместо<input name = "test[]" value = "A"><input name = "test[]" value = "B">.

Gellweiler 22.03.2018 13:15
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
2
74
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Если вы создаете хэш-карту как HashMap<Integer, String>(), но сохраняете ее как HashMap, действительно можно хранить там другие типы.

Например:

    HashMap map = new HashMap<Integer, String>();
    map.put(1, new String[]{"1", "2"});
    System.out.println(map.get(1));

Этот код выполняется без ошибок.

Итак, я думаю, что происходит то, что вы храните его как ссылку на HashMap, которая рассматривается как HashMap<Object, Object>, и поскольку во время выполнения нет информации о фактических универсальных типах, вы можете добавлять объекты других типов в эту коллекцию.

Но если у вас есть другая ссылка на ту же карту с HashMap<Integer, String>, тогда, когда вы вызываете, например, get(), он не сработает, за исключением описанного вами:

    HashMap map = new HashMap<Integer, String>();
    map.put(1, new String[]{"1", "2"});
    System.out.println(map.get(1));
    System.out.println("got here");
    HashMap<Integer, String> otherRef = (HashMap<Integer, String>) map;
    System.out.println(otherRef.get(1)); //<-ClassCastException exception here 

Другие вопросы по теме