Можно ли объявить частный класс как псевдоним?
В мой ответ со вчерашнего дня Я назвал следующий фрагмент кода "хак":
final class MyMap extends HashMap<SomeSuperLongIdentifier, OtherSuperLongIdentifier> {}
// declared MyMap as an alias for readability purposes only
MyMap a = new MyMap();
a.put("key", "val");
Давая ему еще одну мысль, это совсем не похоже на плохую идею, но я могу что-то упустить. Есть ли какие-то ягодицы, которые я пропустил? Является ли это приемлемым (возможно, творческим) способом для объявления псевдонимов на Java?
Ответы
Ответ 1
Недостатком было бы то, что вы не сможете напрямую использовать любые методы, которые возвращают правильно напечатанный Map
, потому что они никогда не вернут MyMap
. Даже если они могут вернуть Map<SomeSuperLongIdentifier, OtherSuperLongIdentifier>
.
Например, вы не сможете использовать методы filter()
в Maps
(предоставленный Коллекции Google). Они принимают экземпляр MyMap
в качестве входных данных, но они возвращают только Map<SomeSuperLongIdentifier, OtherSuperLongIdentifier>
.
Эта проблема может быть несколько уменьшена путем написания вашего MyMap
для делегирования на другую реализацию Map
. Затем вы можете передать возвращаемое значение такого метода в конструктор и по-прежнему иметь MyMap
(без копирования, даже). Конструктор по умолчанию может просто установить делегата на новый экземпляр HashMap
, поэтому использование по умолчанию останется прежним.
Ответ 2
Я думаю, что это удобный способ объявить синонимы типов. Некоторые языки имеют прямую поддержку для этого (например, в Delphi (pascal), вы можете сделать это следующим образом:
type MyMap = HashMap<SomeSuperLongIdentifier, OtherSuperLongIdentifier>;
Поскольку Java не работает, я думаю, вы можете использовать наследование для этого. Вам нужно документировать, что это выражение является просто синонимом, и никто не должен добавлять методы к этому классу. Обратите также внимание на то, что это занимает небольшую память для хранилища VMT.
Ответ 3
Я бы возражал против имени MyMap
: Поскольку вы создаете псевдоним, заставьте его документировать свою цель, указав ему полезное имя. Кроме этого, мне это нравится.
Ответ 4
Я лично этого не делал и буду отмечать его в обзоре, но это вопрос мнения.
Коллекции Google помогают смягчить эту проблему, объявив:
Map<SomeSuperLongIdentifier, OtherSuperLongIdentifier> a = Maps.newHashMap();
Я бы искал способы для кода рефакторинга, чтобы не объявлять так много экземпляров этой Карты, возможно.
Ответ 5
Пока разработчики, использующие ваш код, имеют IDE и могут быстро перейти к определению класса и прочитать комментарии по его назначению (которые есть на месте, нет?), я не вижу в этом ничего плохого.
Ответ 6
Я бы не назвал это псевдонимом. Это не так. Его нельзя использовать взаимозаменяемо с типом, который предполагается сглаживать. Поэтому, если это намерение, оно терпит неудачу.
Ответ 7
Я думаю, что наследование - очень большой пистолет по сравнению с проблемой. По крайней мере, я бы сделал этот класс "alias" final с большим толстым комментарием, описывающим причину его существования.
Ответ 8
Ну, здесь есть два противоречивых аспекта.
- С точки зрения моделирования ваша декларация справа, поскольку она подчеркивает инкапсуляцию, предоставляемую вашим классом.
- С точки зрения кодирования ваша декларация может считаться неправильной, потому что вы добавляете класс только в качестве поддержки моделирования с абсолютно никакой добавленной функцией.
Тем не менее, я считаю ваш подход совершенно правильным (хотя я никогда об этом не упоминал раньше), так как он дает очень высокую оценку (ну, по крайней мере, мне) компилируемую модель: классы из вашей модели отлично отражены в вашем коде, делая ваши спецификации исполняемыми, что очень круто.
Все это заставляет меня сказать, что это определенно отличная идея, если вы поддерживаете ее с документацией.
Ответ 9
Я бы не назвал это взломом. Лично я создал псевдоним с целью объявления параметров родового типа, которые нельзя изменить и создать определенную ясность.
Ответ 10
Вы также не могли использовать эту карту в сериализации, если отправляете на другой jvm, который не имеет вашего класса MyMap.