Проблема с использованием универсальной карты с подстановочными знаками - PullRequest
10 голосов
/ 17 декабря 2009

У меня есть метод, который возвращает map, определенный как:

public Map<String, ?> getData();

Реальная реализация этого метода мне не ясна, но, когда я пытаюсь сделать:

obj.getData().put("key","value")

Я получаю следующее сообщение об ошибке времени компиляции:

Метод put (String, capture # 9-of?) в карте типа не применимо для аргументов (Строка, Строка)

В чем проблема? String не имеет ничего общего?

Заранее спасибо.

Ответы [ 5 ]

15 голосов
/ 17 декабря 2009

Тип возврата

Map<String, ?>

совпадает с

Map<String, ? extends Object>

Означает, что возвращаемый конкретный тип может быть Map<String, AnyClass>. Вы не можете поместить String в AnyClass, следовательно, ошибка.

Хороший общий принцип - не использовать подстановочные знаки в типах возвращаемых методов.

10 голосов
/ 17 декабря 2009

Подстановочный знак означает «параметром типа значения может быть что угодно» - он не означает «вы можете использовать это так, как если бы вы хотели, чтобы оно было». Другими словами, Map<String, UUID> допустимо как Map<String, ?> - но вы не хотели бы иметь возможность помещать в него значение String.

Если вам нужна карта, которая может определенно принимать строковые значения, вам нужно:

Map<String, ? super String>
3 голосов
/ 17 декабря 2009

Map<String, ?> является краткой формой Map<String,? extends Object> и не означает, что что-либо может быть добавлено в качестве значения. В нем говорится, что объект Map может иметь любой тип общего значения, расширяющий Object.

Это означает, что объект Map также может быть HashMap<String, String> или HashMap<String, Integer>. Поскольку компилятор не может проверить, какие типы значений будут приняты, он не позволит вам вызывать методы с типом значения в качестве параметра.

Примечание:

  • Вы можете вызывать методы с типом значения в качестве возвращаемого значения, потому что все должно расширять Object (? Extends Object)
  • A Map<String, ? super String> будет иметь противоположный эффект: вы всегда можете использовать String в качестве параметра, но тип возврата неясен.
0 голосов
/ 17 декабря 2009

Попробуйте это:

public Map<String, Object> getData();
0 голосов
/ 17 декабря 2009

[РЕДАКТИРОВАТЬ] Это действительно неправильно ... Я понял.

Мой первый ответ был:

Это Java: строка не является объектом.

Попробуйте с

obj.getData().put("key",new String("value"));

Но String расширяет Object ... пока я думал, что String был примитивом. Я кое-что узнал ^^

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...