2016-05-07 1 views
2

Почему в языке программирования Java язык не выполнен как обычный класс, например. он не может быть унаследован от него и не имеет каких-либо служебных методов непосредственно в своем классе (например, как String)?Почему классы массивов не имеют каких-либо полезных методов?

Существует множество способов, которые могут быть сконструированы для массивов, например. метода swap(), методы поиска, методы сортировки, сплит/сращивания и т.д.

+6

[Массивы являются объектами (§4.3.1), динамически создаются и могут назначаются переменным типа Object (§ 4.3.3)] (https://docs.oracle.com/javase/specs/jls/se8/html/jls-10.html) –

+0

Эти методы также могут быть написаны для 'Collection'. – bcsb1001

+3

@NoahLevy Тогда, пожалуйста, отредактируйте свой вопрос и перефразируйте его, чтобы избежать путаницы. – Pshemo

ответ

6

ТЛ; др

Это в основном по историческим причинам.


Массивы (и были) обработаны как особый тип данных с самого начала, например, distinct VM opcodes that were intended to deal only with them (обратите внимание, что есть буквально тонн опкодов для обработки массивов!). Это было сделано главным образом таким образом, чтобы производительность массивов была близка к родной (и чтобы JNI мог легко взаимодействовать с ними). Выбор дизайна здесь заключался в том, что потребность в быстрых/массивных типах примитивных/массивных данных была поставлена ​​перед необходимостью «красивого» интерфейса, и поэтому ни примитивы, ни массивы не могут быть «реальными» объектами ради Производительность VM.

Хотя Oak Language Specification (Дуб является прямым Java предка) с указанием Although arrays can be created with new, just as instances of classes are created, arrays are not currently objects. является древних (около 20 лет), она по-прежнему показывает общее представление об этом производительности элегантности компромиссе - сама идее, что повторено в отношении к современной Java около 15 лет спустя в Oracle Arrays 2.0 talk, давая хорошее представление о том, почему так оно и есть, и что мы можем ожидать от него в ближайшем будущем. Я выделил свои пять центов об этом , почему.

Прежде всего, иногда массив намного лучше, чем «поддельный» объект вместо «реального», например. there are some cases (локальный массив с < = 64 элемента), когда массивы просто inlined в код метода (как с локальными переменными). Создание их обычного класса значительно упростило бы эти оптимизации. Однако недостатком является то, что он не позволяет использовать «обычный» класс/объект, поскольку для «обычного» поведения класса/объекта требуется, чтобы среда выполнения обрабатывала все такие вещи, как, например, виртуальная диспетчеризация, конструкторы объектов, GC с графиками композиций и т. д., несущие наказание во время исполнения (см. сноску для комментария). Обратите внимание, что String не имеет этих проблем, потому что он находится под капотом ... только класс оболочки char[] с синтаксическим сахаром!

Также обратите внимание, что вы не можете, например. просто «сортировать» массив - существует много алгоритмов сортировки, которые могли бы быть использованы, поэтому класс массива должен был иметь, если эти утилиты были добавлены вообще. Более того, правильная конструкция такого интерфейса была бы (и - это, как видно на C#) очень сложно (из-за, например, многомерных антенн, нулевых и ненулевых массивов, возможных циклических ссылок и т. Д.), Что, вероятно, вопрос еще больше. OTOH, изменение его, вероятно, приведет к нарушению совместимости - поэтому разработчики Java решили, что лучше, чтобы это было так, как есть. Недавно у нас было a bug with Java lib's own TimSort some time ago - если бы оно было включено в класс массива final, это фактически помешало бы программисту исправить его на месте, переопределив метод!

Есть, однако, как утилита класса java.util.Arrays (со всеми общими утилитами массива может понадобиться) и классов тонкой оболочки, позволяющих надлежащее объектно-ориентированный доступ к массивам (например ArrayList). Вы можете даже написать один самостоятельно и дать вашему ArrayWrapper все, что пожелает ваша душа; будучи программистом, иногда больше около , создавая инструментов, чем около , используя.


Примечание: это является можно достичь реального объекта-подобного поведения на массивах с использованием, например, исходный препроцессор/лексер, поддерживающий синтаксис (аналогично тому, как работает Lombok) или путем исправления компилятора, который, в свою очередь, переписывает псевдозвонки на массивы на действительный статический метод, передавая массив как параметр; например с учетом определения, подобного @ArrayEx(Arrays.class) int[] array;, он преобразует команды, такие как array.sort(); в Arrays.sort(array);, - но, перефразируя Эрика Липперта, его нет, потому что никто не удосужился его кодировать. Если вы решите, что вам это нужно по какой-либо причине, просто напишите код и отправьте патч на OpenJDK или даже просто опубликуйте его на GitHub ... это в основном, как работает OSS chuckle. Project Valhalla приносит некоторую надежду здесь, потому что она по крайней мере тангенциально связана с этим вопросом - вы можете сказать, что наличие объектных примитивных значений - хороший способ проложить путь к реальным объектно-подобным массивам. Вышеупомянутый Arrays 2.0 talk фактически подчеркивает текущее поведение «поддельного» объекта как один из недостатков текущей реализации, упоминая некоторые из вещей, о которых я говорил выше, либо как сознательные варианты выбора, либо возможные возможности и подводные камни. В целом, может быть, эти хорошие люди в Oracle/OpenJDK на самом деле будут добавить их в некоторые будущие расширения Java, кто знает ...

Смежные вопросы