Почему классы-обертки не имеют общего супертипа? - PullRequest
0 голосов
/ 26 апреля 2018

Есть ли какая-то особая причина, по которой классы-оболочки (java.lang.Integer, java.lang.Boolean, ...) не имеют общего супертипа?


Я спрашиваю, потому что было бы очень удобно иметь (например,) WrapperType::getType функцию вдоль классического Object::getClass, которая бы возвращала класс примитивного типа.

В частности, контекст вызывает конструкторов через отражение, когда у вас есть только Class<T> и параметры Object[]

например:

public static <T> T createInstance(Class<T> clz, Object... params) throws Exception

Чтобы получить конструктор, я могу получить типы параметров через:

Class<?>[] c = Arrays
        .stream(params)
        .map(Object::getClass)
        .toArray(Class<?>[]::new);
return clz.getConstructor(c).newInstance(params);

но это, конечно, не удастся с конструкторами типа String::new(char[], int, int);

Если бы этот супертип существовал, я мог бы сделать:

.map( o -> o.getClass().isPrimitive() ? ((WrapperType) o).getType() : o.getClass() )

Я полагаю, что есть особая причина, java разработчики не реализовали это.

Ответы [ 2 ]

0 голосов
/ 26 апреля 2018

Я понимаю, насколько это будет практично, но с точки зрения абстракции это будет большой беспорядок. Допустим, у вас есть упаковщики Integer и Double вместе с остальными в этой семье, у них действительно есть java.lang.Number в качестве супер. Однако между ними и логическим отношением нет семантической связи (с учетом влияния c).

Но ради аргумента, давайте рассмотрим, все ли они в большом ведре и являются ли Wrappers, они все еще числа?

Учитывая историческое отвращение языков к множественному наследованию, наличие чисел сделало бы намного больше сцен, если бы вы выбрали.

После большого революционного изменения языковых возможностей с SE 8 мы теперь можем иметь множественное наследование через интерфейсы, используя стандартные реализации для таких случаев. И если проанализировать дальше, они в рамках логических рассуждений сделают вывод, что в этих случаях требуются контракты, а не наследование; таким образом, даже если это будет сделано, это будет работа для интерфейсов.

Принимая во внимание, что надежный способ реализации этого является довольно новым, и что Оболочки были бы слишком обобщенным способом сделать это, мы можем видеть, что лучше не иметь его. Хотя теперь это возможно, существуют исторические и семантические причины, по которым он не был представлен, по крайней мере, как суперкласс. Абстракция является ключевым здесь. Но ничто не мешает вам вставить фабрику в ваш конвейер или реализовать упомянутый интерфейс.

Строка снизу, ключевые факторы:

  1. Абстракция: это больше похоже на контракт или отношения, являющиеся отношениями
  2. История: обобщения и множественное наследование через интерфейсы
  3. Вообразите размер наследства три, если мы согласимся такие случаи: сначала это обертка, затем число или логическое значение.
0 голосов
/ 26 апреля 2018

Java-дизайнеры, вероятно, не слишком абстрактны в своих решениях и не могут найти много общего между числовыми типами (например, Integer) и нечисловыми типами (например, Boolean), чтобы сгруппировать их по суперклассу.

Хотя все числовые типы расширяются Number, что действительно представляет "числовые значения, которые можно преобразовать в примитивные типы byte, double, float, int, long, short" .

На самом деле все классы-оболочки имеют общий интерфейс Comparable<T> (например, Comparable<Integer> для Integer).

...