Можно ли объявить частный класс как псевдоним?

В мой ответ со вчерашнего дня Я назвал следующий фрагмент кода "хак":

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.