Ошибка компилятора Java Map с общим

// I know that this method will generated duplicate 
// trim keys for the same value but I am just
// trying to understand why we have a compile error:
// The method put(String, capture#11-of ?) in the type
// Map

Почему значение, которое мы хотим поставить map.get (key) , может быть другого типа?

3

12 ответы

Проблема в том, что компилятор знает только, что тип ключа «неизвестен», но не знает, что это неизвестный тип для типа ключа карты и типа, возвращаемого из get ( ) (хотя мы, как люди, понимаем, что это одно и то же).

Если вы хотите, чтобы он работал, вы должны сообщить компилятору, что это тот же неизвестный тип, используя typing ваш метод, например:

void  trimKeyMap(Map map) {
    for (String key : map.keySet()) {
        map.put(StringUtils.trim(key), map.get(key));
    }
}
10
добавлено
Обратите внимание, что достаточно ввести неограниченный V . Это просто, чтобы получить представление о том, что два «неизвестных» являются «теми же неизвестными».
добавлено автор Thilo, источник

It might have been possible for the Java 5 expert group, to add a little more power to the specification of wildcards in generic method argument types. I suspect the enhancement didn't make it due to lack of time in the specs phase. See my own recent question here: How does the JLS specify that wildcards cannot be formally used within methods?

За исключением лучшего решения, вы должны сделать свой метод общим методом :

 void trimKeyMap(Map map){
  for (String key : map.keySet()) {
    map.put(StringUtils.trim(key), map.get(key));
  }
}

You cannot put anything in a Map type, except for the null literal:

Map();
map.put("A", null);//Works
map.put("B", "X");//Doesn't work.

Компилятор не знает know , что тип аргумента значения карты был String . Поэтому он не может позволить вам добавлять что-либо на карту, даже если вы получили значение с самой карты.

3
добавлено

It might have been possible for the Java 5 expert group, to add a little more power to the specification of wildcards in generic method argument types. I suspect the enhancement didn't make it due to lack of time in the specs phase. See my own recent question here: How does the JLS specify that wildcards cannot be formally used within methods?

За исключением лучшего решения, вы должны сделать свой метод общим методом :

 void trimKeyMap(Map map){
  for (String key : map.keySet()) {
    map.put(StringUtils.trim(key), map.get(key));
  }
}

You cannot put anything in a Map type, except for the null literal:

Map();
map.put("A", null);//Works
map.put("B", "X");//Doesn't work.

Компилятор не знает know , что тип аргумента значения карты был String . Поэтому он не может позволить вам добавлять что-либо на карту, даже если вы получили значение с самой карты.

3
добавлено

It might have been possible for the Java 5 expert group, to add a little more power to the specification of wildcards in generic method argument types. I suspect the enhancement didn't make it due to lack of time in the specs phase. See my own recent question here: How does the JLS specify that wildcards cannot be formally used within methods?

За исключением лучшего решения, вы должны сделать свой метод общим методом :

 void trimKeyMap(Map map){
  for (String key : map.keySet()) {
    map.put(StringUtils.trim(key), map.get(key));
  }
}

You cannot put anything in a Map type, except for the null literal:

Map();
map.put("A", null);//Works
map.put("B", "X");//Doesn't work.

Компилятор не знает know , что тип аргумента значения карты был String . Поэтому он не может позволить вам добавлять что-либо на карту, даже если вы получили значение с самой карты.

3
добавлено

Вы можете использовать вывод типа в вспомогательном методе, если вы хотите сохранить подпись чистого метода (клиенту trimKeyMap не нужно использовать общий метод):

void trimKeyMap(final Map void trim(final Map map, final String key) {
    map.put(StringUtils.trim(key), map.get(key));
}

This is called wildcard capture and is discussed more here: http://www.ibm.com/developerworks/library/j-jtp04298/

2
добавлено
Это действительно позор, однако, что javac не мог генерировать некоторые «невидимые локальные общие типы» для обработки этого интуитивного случая «подстановочный знак»
добавлено автор Lukas Eder, источник

? is not a wildcard for any type but the unknown type. So the map only accepts ?-type objects and not String. One conclusion from this (rather strange) fact: We can't add values to collections that are parametized with ?.

1
добавлено

? is different from Object.

A Map is a generic map where you don't know the element type, but it is still being enforced, i.e. it does not allow you to put anything.

1
добавлено

? is different from Object.

A Map is a generic map where you don't know the element type, but it is still being enforced, i.e. it does not allow you to put anything.

1
добавлено

? is different from Object.

A Map is a generic map where you don't know the element type, but it is still being enforced, i.e. it does not allow you to put anything.

1
добавлено

Вы не можете добавлять значения (которые не являются null ) в Collection s и Maps , параметризованные с помощью подстановочного знака . Это связано с тем, что wildcard не является заменой для какого-либо объекта, это просто объект unknown . Таким образом, вы не можете добавить какой-либо (пусть это так) известный объект на карте, которая принимает только unknown .

Вы можете читать только значения.

0
добавлено
Очевидно, вы можете добавить null , но, кроме этого, этот ответ кажется правильным.
добавлено автор Thilo, источник
докажите мне неправду, пожалуйста
добавлено автор darijan, источник
Конечно, но я имел в виду непустые объекты. Я должен был быть более явным.
добавлено автор darijan, источник
Я вспомнил, что несколько раз использовал <?,?> Декларацию, но, как я узнал, я всегда читаю эти переменные ...
добавлено автор Balint Bako, источник
Пытался доказать, что ты ошибаешься, но потерпел неудачу, поэтому теперь я согласен с тобой.
добавлено автор Balint Bako, источник

Вы не можете добавлять значения (которые не являются null ) в Collection s и Maps , параметризованные с помощью подстановочного знака . Это связано с тем, что wildcard не является заменой для какого-либо объекта, это просто объект unknown . Таким образом, вы не можете добавить какой-либо (пусть это так) известный объект на карте, которая принимает только unknown .

Вы можете читать только значения.

0
добавлено
Очевидно, вы можете добавить null , но, кроме этого, этот ответ кажется правильным.
добавлено автор Thilo, источник
докажите мне неправду, пожалуйста
добавлено автор darijan, источник
Конечно, но я имел в виду непустые объекты. Я должен был быть более явным.
добавлено автор darijan, источник
Я вспомнил, что несколько раз использовал <?,?> Декларацию, но, как я узнал, я всегда читаю эти переменные ...
добавлено автор Balint Bako, источник
Пытался доказать, что ты ошибаешься, но потерпел неудачу, поэтому теперь я согласен с тобой.
добавлено автор Balint Bako, источник

Вы не можете добавлять значения (которые не являются null ) в Collection s и Maps , параметризованные с помощью подстановочного знака . Это связано с тем, что wildcard не является заменой для какого-либо объекта, это просто объект unknown . Таким образом, вы не можете добавить какой-либо (пусть это так) известный объект на карте, которая принимает только unknown .

Вы можете читать только значения.

0
добавлено
Очевидно, вы можете добавить null , но, кроме этого, этот ответ кажется правильным.
добавлено автор Thilo, источник
докажите мне неправду, пожалуйста
добавлено автор darijan, источник
Конечно, но я имел в виду непустые объекты. Я должен был быть более явным.
добавлено автор darijan, источник
Я вспомнил, что несколько раз использовал <?,?> Декларацию, но, как я узнал, я всегда читаю эти переменные ...
добавлено автор Balint Bako, источник
Пытался доказать, что ты ошибаешься, но потерпел неудачу, поэтому теперь я согласен с тобой.
добавлено автор Balint Bako, источник
pro.jvm
pro.jvm
3 503 участник(ов)

Сообщество разработчиков Java Scala Kotlin Groovy Clojure Чат для нач-их: @javastart Наш сайт: projvm.com projvm.ru Наш канал: @proJVM Вакансии: @jvmjobs Конфы: @jvmconf

Java & Co
Java & Co
2 370 участник(ов)

Можно обсуждать с матом и без всё, что касается жабы, вплоть до холиваров. НЕ ИМЕЕТ ОТНОШЕНИЯ К САЙТУ JAVARUSH.RU ПРАВИЛА - https://t.me/javarush/75723 Вакансии сюда - https://telegram.me/joinchat/B7IzvUCnfo6d8t3yIxKguQ По вопросам - @thedude

learn.java
learn.java
1 888 участник(ов)

Чат для начинающих и не только Статистика: https://combot.org/chat/-1001083535868 Основной чат - @jvmchat

Java Underground
Java Underground
169 участник(ов)

https://vk.com/javatutorial

Javanese Questions
Javanese Questions
109 участник(ов)

Чат предназначен для обмена знаниями строго в формате в вопрос-ответ. Тема — Java, Kotlin и Android. Вопрос должен быть предварительно прогуглен, понятно и грамотно сформулирован, помечен хэштегами. Ответ — тем более. Куски кода размером в несколько строк можно писать прямо здесь, для больших кусков кода стоит использовать http://gist.github.com/, http://pastebin.com/, https://codeshare.io/ или любой аналогичный сервис. В некоторых случаях можно прикреплять скриншоты. Стикеры и гифки запрещены. Дополнять и уточнять вопросы и ответы — редактированием исходного сообщения. Обсуждения должны приводить к редактированию вопроса/ответа и удаляться. По хештегам можно искать существующие вопросы и овтеты: #вопрос #ответ #git #generics #java #server #awt #javafx #swing #kotlin #anko #tornadofx #ktor #android #recyclerView #performance #arch #network #permissions #storage #async