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

Почему у java есть тип "String", а не "string"?

Класс Wrapper просто прекрасен, и их цель также хорошо понятна. Но почему мы опускаем примитивный тип?

4b9b3361

Ответ 1

Это зависит от того, что вы подразумеваете под "примитивным"

"Примитив" в Java обычно воспринимается как "тип значения". Однако С# имеет ключевое слово string, которое действует точно так же, как Java String, оно просто выделяется редактором по-разному. Это псевдонимы для классов System.String или java.lang.String. Строка не является типом значений на любом языке, поэтому таким образом она не является примитивной.

Если под "примитивным" вы подразумеваете встроенный в язык, то String является примитивным. Он просто использует заглавную букву. Строковые литералы (эти вещи в кавычках) автоматически преобразуются в System.String и + используются для конкатенации. Таким образом, этим маркером они (и массивы) являются такими же примитивными, как ints, longs и т.д.

Во-первых, что такое String?

Строка не является оберткой. Строка является ссылочным типом, тогда как примитивные типы - это типы значений. Это означает, что если у вас есть:

int x = 5;
int y = x;

Память x и y содержит "5". Но с:

String x = "a";
String y = x;

Память x и y содержит указатель на символ "a" (и длину, смещение, указатель ClassInfo и монитор). Строки ведут себя как примитив, потому что они неизменяемы, поэтому обычно это не проблема, однако, если вы, скажем, использовали отражение, чтобы изменить содержимое строки (не делать этого!), оба x и y увидели бы изменение. Фактически, если у вас есть:

char[] x = "a".toCharArray();
char[] y = x;
x[0] = 'b';
System.out.println(y[0] == 'b'); // prints "true"

Поэтому не просто используйте char [] (если это не то поведение, которое вы хотите, или вы действительно пытаетесь уменьшить использование памяти).

Каждый Object является ссылочным типом - это означает все классы, которые вы пишете, каждый класс в структуре и даже массивы. Единственными вещами, которые являются типами значений, являются простые числовые типы (int, long, short, byte, float, double, char, bool и т.д.)

Почему переменная String не работает как char []?

Есть несколько причин для этого, но в основном это сводится к деталям психологии и реализации:

  • Представьте себе хаос, который у вас был бы, если бы вы передали строку в другую функцию, и эта функция каким-то образом изменила ее. Или что, если он где-то сэкономил и изменил его в будущем? С большинством ссылочных типов вы принимаете это как часть этого типа, но разработчики Java решили, что, по крайней мере, для строк, они не хотели, чтобы пользователи беспокоились об этом.
  • Строки не могут обрабатываться атомарно, т.е. многопоточность/синхронизация станут проблемой.
  • Строковые литералы (вещи, которые вы помещаете в код в кавычках) могут быть неизменными на уровне компьютера 1 (из соображений безопасности). Это можно было бы получить, скопировав их все в другую часть памяти при запуске программы или использовании copy-on-write, но это медленно.

Почему у нас нет версии строки типа value?

В основном, характеристики производительности и реализации, а также сложность наличия двух разных типов строк. Другие типы значений имеют фиксированный объем памяти. Int всегда 32 бита, длинный всегда 64 бит, bool всегда 1 бит и т.д. 2 Между прочим, это означает, что они могут быть сохранены в стеке, так что все параметры к функции жить в одном месте. Кроме того, создание гигантских копий строк по всему месту приведет к гибели производительности.

См. также: В С#, почему String является ссылочным типом, который ведет себя как тип значения?. Относится к .NET, но это так же применимо в Java.

1 - В C/С++ и других языках с компиляцией изначально это верно, потому что они помещаются в сегмент кода процесса, который ОС обычно останавливает вас от редактирования. В Java это на самом деле обычно неверно, поскольку JVM загружает файлы классов в кучу, поэтому вы можете редактировать строку там. Однако нет причин, по которым программа Java не может быть скомпилирована (есть инструменты, которые делают это), а некоторые архитектуры (в частности, некоторые версии ARM) непосредственно выполняют байт-код Java.

2 - На практике некоторые из этих типов различаются по размеру на уровне машины. E.x. bools хранятся как WORD-размер в стеке (32 бит на x86, 64 бит на x64). В классах/массивах к ним можно относиться по-разному. Это все детали реализации, которые остались до JVM - спецификация говорит, что bools являются истинными или ложными, и машина может понять, как это сделать.

Ответ 2

Примитивным типом для String является char[].

Это верно для многих языков (C, Java, С#, С++ и многих других...).

Ответ 3

Строки

могут быть произвольной длины. отцы java не хотели иметь примитивный тип, для которого они не могли назначить конкретный объем памяти. это одна из главных причин, по которым строка не является примитивной в java.

Ответ 4

Строка - это особый случай. Все реальные примитивные типы (int, long и т.д.) Передаются по значению и реализуются непосредственно в JVM. String является ссылочным типом, и поэтому он рассматривается как любой другой класс (прописная буква, pass-by-reference...), за исключением того, что у компилятора есть специальные крючки для работы с ним, как встроенный тип (+ для конкатенации строк, например).

Поскольку он уже является ссылочным типом, ему не нужен класс-оболочка, такой как Integer, чтобы иметь возможность использовать его как класс (например, в коллекциях)

Ответ 5

Primitive?

Если Java нет примитива для строк. Примитивами являются int, float, double, boolean и т.д.... и char.

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

Как они его реализовали? Сохранение значения, которое оно представляет в массиве char.

Inmutability

Но они обеспечили невозможность. Когда у вас есть ссылка на объект String, вы знаете, что можете свободно передавать его другим объектам, зная, что значение, указанное этой ссылкой, не изменится. Все методы, которые изменяют строки, возвращают другой экземпляр строки, поэтому он не меняет значения, представленные другими ссылками на String.

Может ли быть другим способом (например, в .Net)

Да. Они могли бы определить зарезервированную строку слова, а компилятор выполнил преобразование.

Но они не...

Ответ 6

a Строка - это массив из char. Поскольку это массив, он не может быть примитивным!: -)