Почему String.length () является методом? - PullRequest
14 голосов
/ 04 января 2012

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

Это просто метод получения или он выполняет какие-то вычисления?

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

Ответы [ 8 ]

19 голосов
/ 04 января 2012

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

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

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

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

4 голосов
/ 04 января 2012

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

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

3 голосов
/ 04 января 2012

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

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

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

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

По сути, это делается так, потому что это хорошая практика проектированиясделать это.Это оставляет возможность изменить реализацию String на более позднем этапе, не нарушая код для всех.

3 голосов
/ 04 января 2012

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

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

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

3 голосов
/ 04 января 2012

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

2 голосов
/ 04 января 2012

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

1 голос
/ 04 января 2012

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

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

1 голос
/ 04 января 2012

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

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

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