Почему методы конвертера в классах библиотеки Java нестатичны? - PullRequest
0 голосов
/ 30 октября 2019

Я вижу, что несколько методов конвертации в классах библиотеки Java нестатичны. Пример: toEpochMilli () из Instant, toArray () из ArrayList. Вместо этого у нас могут быть статические методы, такие как toEpochMilli (Instant Instant) и toArray (ArrayList arrayList) для достижения той же цели, верно? Есть ли какая-то конкретная причина, по которой эти методы нестатичны?

Ответы [ 2 ]

4 голосов
/ 30 октября 2019

В комментарии вы написали:

Да, это больше похоже на служебный метод, а служебные методы обычно являются статическими

, которыепохоже, очень хорошо отражает мышление вашего вопроса. Есть две проблемы с этим. С одной стороны, не существует четкого определения «вспомогательного метода», что делает эту классификацию очень субъективной.

Во-вторых, тот факт, что вспомогательные методы часто (или были) реализованы как static методы, не означает, чтоэто фактический шаблон проектирования, который нужно скопировать, просто потому, что это было сделано ранее.

Это скорее исторический компромисс. До Java 8 не было методов default, поэтому каждый метод, добавленный к интерфейсу, должен был быть реализован, даже если он был делегирован другому вспомогательному методу.

В качестве практического примера, если sort былдобавленный к интерфейсу List в самом начале, каждый разработчик List должен был иметь с ним дело. Поэтому он был добавлен как static метод к Collections классу , что не означает, что кто-то считает

Collections.sort(list, comparator); // no import static by that time

лучше, чем

list.sort(comparator);

Или то, что у них одна реализация, которая подходит всем. Это не только упустило возможности оптимизации для реализаций, таких как ArrayList, но и подразумевало, что ошибочное применение его к неизменяемому списку останется незамеченным, когда список окажется в правильном порядке.

Теперь, когда у нас есть default методов, List имеет такой sort метод , поэтому разработчикам по-прежнему не требуется иметь дело с этим, но они могут переопределять метод, когда это уместно. Таким образом, ArrayList имеет оптимизированную версию, неизменяемые списки генерируются безоговорочно, а возвращенная реализация Collections.synchronizedList может синхронизировать всю операцию.

Категоризация как «служебный метод» здесь никогда не играла никакой роли. Обратите внимание, что другие языки работают с ним по-другому, например, с помощью расширенных методов, которые имеют свои плюсы и минусы сами по себе, но также показывают, что необходимость писать вызов служебного метода как static метод не является реальной целью. На самом деле все наоборот.

0 голосов
/ 30 октября 2019

Статика не работает так же хорошо с наследованием:

List<String> list1 = new ArrayList<>();
List<String> list2 = new LinkedList<>();

list1.size()
list2.size()
ArrayList.staticSize((ArrayList) list1)
LinkedList.staticSize((LinkedList) list2)
List.staticSize(list1); // NOT POSSIBLE

Хотелось бы что-то вроде:

interface List {
    static staticSize(List list) {
        return list.size();
    }
}

Но тогда все же используется нестатический size().

Нет статической отправки, полиморфизм. (JVM имеет некоторую поддержку для других языков.)

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