- 1
- 2
- 3
public class StringToObjectMap extends HashMap<String, Object> {
public StringToObjectMap(Map<? extends String, ? extends Object> map)
Нашли или выдавили из себя код, который нельзя назвать нормальным, на который без улыбки не взглянешь? Не торопитесь его удалять или рефакторить, — запостите его на говнокод.ру, посмеёмся вместе!
+79
public class StringToObjectMap extends HashMap<String, Object> {
public StringToObjectMap(Map<? extends String, ? extends Object> map)
Нет слов выразить мою печаль.
taburetka 13.02.2013 21:43 # 0
absolut 13.02.2013 22:05 # 0
bormand 14.02.2013 05:19 # +2
http://docs.oracle.com/javase/tutorial/java/generics/upperBounded.html
Конструктор примет любой мап, у которого ключ это стринг или его потомок, а значение - любой объект. К примеру Map<String, Test>
absolut 14.02.2013 07:39 # +1
3.14159265 14.02.2013 16:37 # +1
public StringToObjectMap (Map<String, ?> map)
Ибо ? extends Object==?. Это как писать class A extends Object вместо class A
А вообще желающим постичь женерики в жабе рекомендую читать эпичный труд Анжелики Лагнер.
bormand 14.02.2013 16:49 # 0
http://www.angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.html
this?
3.14159265 14.02.2013 16:53 # 0
roman-kashitsyn 16.02.2013 09:17 # 0
Standard C++ IOStreams and Locales (ISBN-10: 0321585585)
TarasB 14.02.2013 09:23 # 0
govnomonad 14.02.2013 09:41 # 0
bormand 14.02.2013 10:37 # 0
roman-kashitsyn 14.02.2013 10:39 # +1
tir 14.02.2013 10:46 # 0
roman-kashitsyn 14.02.2013 10:58 # 0
В скале этот косяк пофиксили, там ковариантность/контравариантность типа определяется на уровне класса, чтобы всем его пользователья не приходилось писать эти экзистенциальные знаки вопроса.
P.S. Все @SuppressWarnings локализованы.
bormand 15.02.2013 05:43 # 0
Т.е. я могу писать @SuppressWarnings("НеобработанноеИсключение")?
TarasB 14.02.2013 10:49 # 0
roman-kashitsyn 14.02.2013 11:01 # 0
TarasB 14.02.2013 10:49 # 0
Чем интерфейс Map<String,Base> отличается от интерфейса Map<String,Derived>? Очевидно, что первый - подмножество второго. То есть в функцию, требующую первый, можно давать второй.
Хотя не, в Map<String,Base> можно засунуть Base, и тогда объект при выходе из метода будет вместо Derived содержать Base, что неправильно. ШАБЛОНОПРОБЛЕМЫ.
Вот был тупо только Map<Object,Object>, не было бы проблемы.
roman-kashitsyn 14.02.2013 11:05 # 0
tir 14.02.2013 09:28 # +3
absolut 14.02.2013 09:53 # +3
tir 14.02.2013 09:39 # 0
wvxvw 14.02.2013 22:13 # 0
roman-kashitsyn 14.02.2013 22:42 # 0
wvxvw 14.02.2013 22:51 # 0
roman-kashitsyn 14.02.2013 23:22 # 0
wvxvw 14.02.2013 23:45 # 0
roman-kashitsyn 15.02.2013 00:07 # +3
tir 15.02.2013 16:17 # 0
roman-kashitsyn 15.02.2013 16:22 # +1
tir 15.02.2013 16:37 # +2
просто в стандартном гете ожидаемый параметр - Object
как следствие, для Map<String, Object> можно сделать get(24) и получить null
2. всегда можно впихнуть дополнительные хелперные методы в класс, для более удобной работы. о них автор тоже умолчал
в целом, в расширении мэпа не вижу ничего плохого
nafania217518 15.02.2013 16:47 # +1
2. В дальнейшем от этого недоразумения наследуются несколько раз, делая видимость гибкой архитектуры, когда вместо одного наследника передается инстанс другого, но все в итоге кастуется к этой говномапе.
3.14159265 15.02.2013 16:48 # 0
Верно. Я тоже так делаю. Только название громоздкое.
Например что-то такое:
SqlMap extends HashMap<String, Object>.
SqlMap - короткое название. Можно еще фабричные методы туда допилить.
SqlMap.make ("a",1, "b",2, "c",3);
roman-kashitsyn 15.02.2013 16:55 # 0
К примеру, у меня в проекте есть класс Structs, в котором есть методы Есть класс SafeGet с методами и т.д.
tir 16.02.2013 18:58 # 0
Например
class Params extends HashMap<String, Object>
p = new Params();
...
p.getInt("prop1")
p.getLong("prop2")
wissenstein 18.02.2013 01:13 # 0
…
p.getMinimalAge();
p.getDefaultTimeout();
tir 18.02.2013 08:50 # 0
roman-kashitsyn 18.02.2013 09:10 # +1
Мне нравится идея построения дерева абстракций снизу вверх, когда несколько простых абстраций (вроде Map) используются для построения более высокоуровневой абстракции с другим интерфейсом. Каждый следующий уровень использует услуги нижнего, по возможности не раскрывая реализации.
Особенно подозрительно наследование от конкретных, т.е. не абстрактных классов.
Вот и в вашем случае, унаследовав класс Params от HashMap, вы нарушили инкапсуляцию, раскрыв реализацию. Кроме того, вы лишили себя возможности поддержания части инвариантов класса, ведь пользователи имеют возможность вызывать методы HashMap, даже если они не имеют никакого отношения к абстракции параметров (addAll? empty?).
tir 18.02.2013 09:21 # +1
П.С. Если мне потребуется изменить поведение - я определю новый класс, ничего не наследующий и спрячу мэп внутрь.
roman-kashitsyn 18.02.2013 10:29 # 0
wissenstein 18.02.2013 19:40 # 0
:P