Почему стандартные классы иногда имеют, казалось бы, не связанные методы?
Изучая стандартную библиотеку Java и ее классы, я не мог не заметить, что некоторые из этих классов имеют методы, которые, по моему мнению, не имеют никакого отношения к причине этих классов.
Методы, о которых я говорю, это, например, Integer # getInteger, который извлекает значение некоторого "системного свойства", или System # arraycopy, назначение которого четко определяется его именем. Тем не менее, оба эти метода кажутся неуместными, особенно первый, который по какой-то причине связывает работу с системными ресурсами с классом-оболочкой примитивного типа.
С моей нынешней точки зрения такая политика размещения методов выглядит как нарушение основного принципа разработки ООП: каждый класс должен быть посвящен решению своего конкретного набора проблем, а не превращаться в швейцарский армейский нож. Но так как я не думаю, что Java-дизайнеры - идиоты, я предполагаю, что за решением поставить эти методы именно там, где они есть, лежит некоторая логика. Поэтому я был бы признателен, если бы кто-нибудь смог объяснить, что это за логика на самом деле.
Спасибо!
Обновить
Несколько человек намекают на тот факт, что у Java есть свои нелогичные вещи, которые просто являются пережитками бурного прошлого. Тогда я переформулирую свой вопрос: почему Java так не желает отмечать свои архитектурные недостатки как устаревшие, поскольку не похоже, что существующие устаревшие функции, вероятно, будут прекращены в любом наблюдаемом будущем, а создание устаревших функций действительно помогает воздерживаться от их использования в новых создал код?
3 ответа
Это хорошая вещь для удивления. Я знаю о более поздних функциях (таких как дженерики, лямбда и т. Д.), В списках рассылки есть несколько блогов и постов, которые объясняют выбор, сделанный создателями библиотек. Это очень интересно читать.
В вашем случае я ожидаю, что ответ не слишком интересный. Причину, по которой они были сделаны, трудно сказать. Но оба класса существуют с JDK1.0. В те дни качество программирования в целом (а также Java и OO в частности), возможно, было ниже (то есть было меньше общепринятых практик, создателям библиотек приходилось самим придумывать много парадигм). Также были и другие ограничения в те времена, такие как Object
создание дорого.
Многие из этих неуклюже разработанных методов и классов теперь имеют лучшую альтернативу. (Увидеть Date
и пакет java.time
) arraycopy
вы ожидаете быть добавлены к Arrays
класс, но, к сожалению, его там нет.
В идеале оригинальный метод на некоторое время будет устаревшим, а затем удален. Многие библиотеки следуют этой стратегии. Тем не менее, Java очень консервативна в этом отношении и осуждает только те вещи, которые на самом деле не должны использоваться (такие как Thread.stop()
, Я не думаю, что метод был удален в Java из-за устаревания. Это означает, что довольно легко обновить ваше программное обеспечение до более новой версии Java, но это происходит за счет того, что в библиотеках остается некоторая путаница.
Тот факт, что java настолько консервативен в отношении совместимости новых версий JDK/JRE со старым исходным кодом и двоичными файлами, любим и ненавистен. Для вашего хобби-проекта или небольшого активно развивающегося проекта обновление до новой JVM, которая удаляет устаревшие функции через несколько лет, не так уж сложно. Но не забывайте, что многие проекты активно не разрабатываются или разработчикам трудно безопасно вносить изменения, например, из-за отсутствия надлежащего регрессионного теста. В этих проектах изменения API-интерфейсов требуют значительных затрат времени и подвергаются риску появления ошибок.
Кроме того, библиотеки часто пытаются поддерживать более старые версии Java, а также более новую версию, у них будет проблема, когда методы будут удалены.
Пример Integer- это, вероятно, просто дизайнерское решение. Если вы хотите неявно интерпретировать свойство как Integer, используйте java.lang.Integer. В противном случае вам придется предоставить метод получения для каждого типа java.lang. Что-то вроде:
- System.getPropertyAsBoolean (String)
- System.getPropertyAsByte (String)
- System.getPropertyAsInteger (String)...
И для каждого типа данных вам потребуется по умолчанию один дополнительный метод: - System.getPropertyAsBoolean(String, boolean) - System.getPropertyAsByte(String, byte) ...
Поскольку у java.lang-Types уже есть некоторые способности приведения (Integer.valueOf(String)), я не слишком удивлен, обнаружив здесь метод getProperty. Удобство в торговле за нарушение принципов чуть-чуть.
Я думаю, чтодля System.arraycopy это операция, которая зависит от операционной системы. Вы, вероятно, копируете память из одного места в другое очень эффективным способом. Если бы я хотел скопировать такой массив, я бы искал его в java.lang.System
"Я предполагаю, что в решении о размещении этих методов именно там, где они есть, есть некоторая логика"
Хотя это часто так, я обнаружил, что когда что-то не так, это предположение обычно и вводит вас в заблуждение.
Язык постоянно развивается, со дня, когда кто-то предлагает новый язык, до дня, когда он устарел. Между этими крайностями находятся некоторые фазы, через которые проходит язык. Особенно, если кто-то тратит деньги на это и хочет, чтобы люди его использовали, часто происходит очень специфическая фаза, непосредственно перед или после первого выпуска:
Этап "нам нужно, чтобы это работало вчера".
Вот где такие вещи случаются, у вас есть почти полный язык, но программисты должны сделать что-то, чтобы показать, на что способен язык, или конкретное приложение нуждается в функции, которая не была разработана для языка.
Итак, где мы добавим эту функцию? - хорошо, когда это имеет больше смысла для конкретного программиста, задача которого состоит в том, чтобы "заставить его работать вчера".
Логика может заключаться в том, что именно здесь функция имеет наибольшее значение, поскольку она нигде не принадлежит и не заслуживает своего собственного класса. Это также может быть что-то вроде: до сих пор мы никогда не делали копию массива, не используя system.. давайте поместим в него arraycopy и сохраним для каждого дополнительное включение..
- в следующем поколении языка люди не будут перемещать эту функцию, поскольку некоторые опытные программисты будут жаловаться. Таким образом, функция может быть продублирована и найдена там, где она имеет больше смысла.
гораздо позже он будет помечен как устаревший и удален, если кто-нибудь захочет его почистить.