длина и длина () в Java

Почему у нас длина массива как атрибута, array.length , а для String у нас есть метод str.length() ?

Есть ли какая-то причина?

Позвольте мне сначала выделить три разных способа для аналогичной цели.

lengthмассивы ( int[] , double[] , String[] ) – знать длину массивов

length()связанный с String объект ( String , StringBuilder и т. д.) – знать длину строки

size()Объект коллекции ( ArrayList , Set и т. д.) – знать размер коллекции

Теперь забудьте о length() рассмотреть только length и size() .

length – это не метод, поэтому совершенно очевидно, что он не будет работать с объектами. Он работает только с массивами.
size() его имя описывает его лучше, и поскольку это метод, он будет использоваться в случае тех объектов, которые работают с коллекцией (фреймворками коллекции), как я сказал там.

Теперь length() :
Строка не является примитивным массивом (поэтому мы не можем использовать .length ), а также не коллекцию (поэтому мы не можем использовать .size() ), поэтому нам также нужен другой, который является length() (сохраняйте различия и подавайте цель).

Как ответ на вопрос почему?
Я считаю это полезным, легким для запоминания и использования и дружелюбия.

Немного упрощенная, вы можете думать об этом как о массивах, которые являются особым случаем, а не обычными classами (немного похожими на примитивы, но нет). Строка и все коллекции являются classами, поэтому методы получения размера, длины или аналогичных вещей.

Я предполагаю, что причиной во время разработки была производительность. Если они создали его сегодня, они, вероятно, придумали что-то вроде массивов коллекции с поддержкой массивов.

Если кому-то интересно, вот небольшой fragment кода, иллюстрирующий разницу между двумя в сгенерированном коде, сначала источник:

 public class LengthTest { public static void main(String[] args) { int[] array = {12,1,4}; String string = "Hoo"; System.out.println(array.length); System.out.println(string.length()); } } 

Вырезая путь не столь важной части байтового кода, запуск javap -c в classе приводит к следующим двум двум строкам:

 20: getstatic #3; //Field java/lang/System.out:Ljava/io/PrintStream; 23: aload_1 24: arraylength 25: invokevirtual #4; //Method java/io/PrintStream.println:(I)V 28: getstatic #3; //Field java/lang/System.out:Ljava/io/PrintStream; 31: aload_2 32: invokevirtual #5; //Method java/lang/String.length:()I 35: invokevirtual #4; //Method java/io/PrintStream.println:(I)V 

В первом случае (20-25) код просто запрашивает JVM для размера массива (в JNI это было бы вызовом GetArrayLength ()), тогда как в случае String (28-35) ему нужно выполнить вызов метода для получения длины.

В середине 1990-х годов, без хороших JIT и т. Д., Он бы полностью уничтожил производительность, чтобы иметь только java.util.Vector (или что-то подобное), а не конструкцию языка, которая на самом деле не вела себя как class, но была быстрой. Разумеется, они могли маскировать свойство как вызов метода и обрабатывать его в компиляторе, но я думаю, что было бы еще более запутанным иметь метод для чего-то, что не является реальным classом.

Рассматривать:

 int[] myArray = new int[10]; String myString = "hello world!"; List myList = new ArrayList(); myArray.length // Gives the length of the array myString.length() // Gives the length of the string myList.size() // Gives the length of the list 

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

В конечном счете это просто несогласованность, которая сложилась, которая определенно была бы исправлена, если бы язык был переработан с нуля. Насколько я знаю, никакие другие языки (C #, Python, Scala и т. Д.) Не делают то же самое, так что это, вероятно, просто небольшой недостаток, который оказался частью языка.

Вы получите сообщение об ошибке, если в любом случае вы используете неверный.

.length является одноразовым свойством Java. Он используется для определения размера одномерного массива .

.length() – это метод. Он используется для определения длины String . Это позволяет избежать дублирования значения.

В Java массив хранит свою длину отдельно от структуры, которая фактически хранит данные. Когда вы создаете массив, вы указываете его длину и становится определяющим атрибутом массива. Независимо от того, что вы делаете с массивом длины N (значения изменения, нулевые значения и т. Д.), Он всегда будет массивом длины N.

Длина строки является случайной; это не атрибут String, а побочный продукт. Хотя Java-строки на самом деле неизменяемы, если бы можно было изменить их содержимое, вы могли бы изменить их длину. Сбрасывание последнего символа (если это было возможно) уменьшило бы длину.

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

Я рассматриваю это как оправдание для одного с атрибутом, а другой – с помощью метода. По правде говоря, это может быть непреднамеренная непоследовательность, но это всегда имеет смысл для меня, и это всегда то, как я думал об этом.

Мне учили, что для массивов длина не извлекается методом из-за следующего страха: программисты просто назначили длину локальной переменной перед входом в цикл (думаю, цикл for, где условное использует длину массива.) Программист предположительно сделает это, чтобы обрезать вызовы функций (и тем самым повысить производительность). Проблема в том, что длина может измениться во время цикла, а переменная не будет.

Всякий раз, когда создается массив, задается его размер. Таким образом, длину можно рассматривать как атрибут конструкции. Для String это по существу массив символов. Длина – это свойство массива char. Нет необходимости ставить длину как поле, потому что не все нуждается в этом поле. http://www.programcreek.com/2013/11/start-from-length-length-in-java/

Я просто хочу добавить несколько замечаний к большому ответу Фредрика .

Спецификация языка Java в разделе 4.3.1

Объект – это экземпляр classа или массив .

Таким образом, массив действительно играет особую роль в Java. Я действительно удивляюсь, почему.

Можно утверждать, что текущий массив реализации / был важен для лучшей производительности. Но это внутренняя структура, которую не следует раскрывать.

Разумеется, они могли маскировать свойство как вызов метода и обрабатывать его в компиляторе, но я думаю, что было бы еще более запутанным иметь метод для чего-то, что не является реальным classом.

Я согласен с Фредриком в том, что оптимальный выбор оптимального компилятора был бы лучшим выбором. Это также решит проблему: даже если вы используете свойство для массивов, вы не решили проблему для строк и других (неизменяемых) типов коллекций, потому что, например, string основана на массиве char как вы можете видеть на определение classа String :

 public final class String implements java.io.Serializable, Comparable, CharSequence { private final char value[]; // ... 

И я не согласен с тем, что это будет еще более запутанным, потому что массив наследует все методы из java.lang.Object .

Как инженер мне действительно не нравится ответ «Потому что это всегда было так». и пожелал бы лучшего ответа. Но в этом случае это похоже.

ТЛ; др

На мой взгляд, это дизайнерский недостаток Java и не должен реализовываться таким образом.

  • Преобразование строки в заголовок
  • NSString - преобразовать только в чистый алфавит (т.е. удалить акценты + пунктуацию)
  • Java String.indexOf и пустые строки
  • найти местоположение символа в строке
  • Regex соответствует строке, содержащей два имени в любом порядке
  • Как я могу безопасно преобразовать массив байтов в строку и обратно?
  • swift Как удалить дополнительный строковый символ
  • Использует ли StringBuilder больше памяти, чем конкатенация строк?
  • Извлечь числовую часть строк смешанных чисел и символов в R
  • Обратное строковое слово Word в Word
  • Число регулярных выражений от 1 до 100
  • Давайте будем гением компьютера.