Подтвердить что ты не робот

Почему метод String.length()?

Если объект String является неизменным (и, следовательно, он, очевидно, не может изменить его длину), почему метод length(), а не просто public final int length, например, в массиве?

Это просто метод getter, или он делает какой-то расчет?

Просто пытаюсь понять логику этого.

4b9b3361

Ответ 1

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

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

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

Итак, позвольте действительно инвертировать вопрос (это то, что вы должны делать, когда разрабатываете класс, который должен оставаться неизменным на протяжении десятилетий): Что здесь дает поле, почему бы просто не сделать его методом?

Ответ 2

Возможно, метод .length() считался более совместимым с соответствующим методом для StringBuffer, для которого, очевидно, понадобилась бы более чем переменная-член final.

Класс String был, вероятно, одним из первых классов, определенных для Java, когда-либо. Возможно (и это просто предположение), что реализация использовала метод .length() до final переменных-членов даже существовала. Это не займет много времени, прежде чем использование метода будет хорошо внедрено в тело существующего в то время кода Java.

Ответ 3

Возможно, потому что length() происходит из интерфейса CharSequence. Метод является более разумной абстракцией, чем переменная, если она будет иметь несколько реализаций.

Ответ 4

Это фундаментальный принцип инкапсуляции.

Часть инкапсуляции заключается в том, что класс должен скрывать свою реализацию от своего интерфейса (в смысле "дизайн по контракту" интерфейса, а не в смысле ключевого слова Java).

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

Ответ 5

Вы всегда должны использовать методы доступа в публичных классах, а не в публичных полях, независимо от того, являются ли они окончательными или нет (см. пункт 14 в "Эффективной Java" ).

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

Эффективная Java обеспечивает действительно хорошее эмпирическое правило:

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

В принципе, это делается так, потому что это хорошая практика проектирования. Он оставляет место для изменения реализации String на более позднем этапе без нарушения кода для всех.

Ответ 6

Строка использует инкапсуляцию, чтобы скрыть свои внутренние данные от вас. Неизменяемый объект по-прежнему свободен иметь изменяемые внутренние значения, если его внешнее видимое состояние не изменяется. Длину можно было лениво вычислить. Я рекомендую вам взглянуть на исходный код String.

Ответ 7

Проверка исходного кода String в Открыть JDK это только геттер.

Но, как указывает @SteveKuo, это может отличаться в зависимости от реализации.

Ответ 8

В большинстве современных реализаций jvm Подстрока ссылается на массив char исходного String для содержимого, и для определения собственного содержимого ему нужны поля начала и длины, поэтому метод length() используется как getter. Однако это не единственный возможный способ реализации String.

В другой возможной реализации каждая строка может иметь свой собственный массив char, и поскольку массивы char уже имеют поле длины с правильной длиной, было бы избыточно иметь один для объекта String, так как String.length() метод, который нам не нужно делать, и может просто ссылаться на внутреннюю array.length.

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