Почему String - единственный класс, для которого в Java существуют литералы?

StackOverflow https://stackoverflow.com/questions/1404887

  •  05-07-2019
  •  | 
  •  

Вопрос

Почему это java.lang.String единственный класс, для которого существуют два способа создания:

1) Обычным способом с "new" ключевое слово.

String s = new String("abc");

2) С помощью String литерал (который доступен только с String класс)

String s = "abc";

Так почему же они существуют String литералы и никаких литералов для каких-либо других классов??

Это было полезно?

Решение

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

Позже, когда автобокс стал частью стандартного компилятора, вы также можете создавать числовые объекты-оболочки таким образом, т.е.

Integer i = 123;

как упоминает Том Хотин-таклайн в комментариях к вопросу.

Другие советы

Короткий ответ, потому что дизайнеры языка чувствовали это так.

Я думаю, что String - такой распространенный класс, что они сделали исключение. Я уверен, что есть и другие подобные исключения (см. Комментарий Тома Хоутинса)

Оставляя в стороне автобокс (который не учитывает IMO - литералы относятся к примитивным типам, а не к классам; существует просто неявное преобразование в класс-оболочку), конструктор String (String) на самом деле полезно. Для этого требуется копия символьных данных, что означает, что если строка original мала, но с большой подложкой char [] , новая строка не зависит от нее.

Это может быть важно, например, если вы читаете короткие строки из файла.

Что касается того, почему существуют строковые литералы: потому что они полезны. Что бы вы имели вместо этого? Хотите ли вы заставить разработчиков использовать:

String x = new String(new char[] { 'h', 'e', 'l', 'l', 'o' });

и в то же время не проходить стажировку?

Для какого другого класса вы бы хотели получить литерал? Возможно, были бы полезны литералы для карт и списков - я не могу вспомнить, появятся они в Java 7 или нет. Вы можете думать об инициализаторах массива как о «немного похожем на литерал». в том, что это сокращение для инициализации объекта.

Я полагаю, поскольку String является таким фундаментальным типом данных, они рассматривают его на том же уровне, что и примитивы.

Кстати,

new String("abc");

фактически создает 2 Строки:

  1. интернированный, ссылку на который вы теряете
  2. новый экземпляр с тем же содержимым

Лично я никогда не видел необходимости использовать конструктор String .

Типы объектов, которые имеют литералы: Строки , null и литералы класса .

Также можно использовать инициализаторы для массивов и примитивные литералы также можно использовать для создания объектов, если они используются в качестве инициализаторов, которые соответствуют «двум способам создания». в простом синтаксисе, не будучи истинными литералами (они могут использоваться только для инициализации значения, а не во всех местах, где может возникнуть выражение объекта).

Если вы используете другие методы, такие как сериализация и рефлексия, вы можете нарушить "два способа создания". тоже.

Предполагается, что Java 7 предоставит возможность создавать начальные коллекции с помощью литералов, очень похожих на литералы массива:

Последнее, что я проверял:

Integer wInt = 1;

Работает просто отлично.

Последняя форма создания также включает в себя интернирование строк. То есть, если у вас есть код:

String s = "abc";
String t = "abc";

компилятор оптимизирует это, и вы получите две ссылки на один и тот же объект String. (s == t будет правдой).

Строковое интернирование работает и для строковых выражений.

Конечно, есть также литералы для всех примитивных числовых типов, а также логические значения true и false, а также символы. Полагаю, вы могли бы ответить, что в своем вопросе вы технически сказали «никаких литералов для любых других классов ». Хорошо. Я думаю, что кто-то указал, что "ноль" это буквальный объект, так что ваше утверждение технически неточно, но я думаю, что это единственный другой пример.

Но тогда возникает следующий очевидный вопрос: для каких других классов вы хотели бы иметь литералы? Если бы вы разрабатывали язык, как бы выглядел литерал BufferedReader? Или литерал ResultSet? Или JCheckBox?

Теоретически можно сказать, что, например, " Файловый литерал " это имя файла, заключенное в некоторый специальный разделитель, например " $ / home / bob / myfile.txt $ " ;. Но тогда кто-то может сказать: как насчет JButton, мы не можем сделать для этого литерал, например, с помощью текста кнопки и ActionListener, который она запускает, и соответствующих разделителей, таких как "% Submit, SubmitListener% " ;. А что касается Sockets, мы не можем поместить имя хоста в какой-то специальный разделитель и т. Д. Я думаю, что совершенно очевидно, что у нас быстро закончатся знаки препинания для использования в качестве разделителей. Поэтому нам пришлось бы написать какой-то текст, чтобы определить, о каком классе мы говорим, например, сказать File (" /home/bob/myfile.txt") или Socket (" www.example.com " , 631). Но это очень похоже на конструктор, и мы вернемся к тому, что на самом деле сделали авторы Java.

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

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

Строковые литералы - это удобное сокращение с хорошо установленным приоритетом (в Си) и синтаксисом. Если Java-дизайнеры хотели заманить программистов на C ++, там должны быть строковые литералы. К счастью, обработка строк в Java намного удобнее, чем в C ++.

Ни один другой стандартный объект не имел де-факто синтаксиса - как бы вы написали литерал карты?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top