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

Почему новое ключевое слово не требуется для String

Я новичок в java.

В java, String есть class. Но нам не нужно использовать ключевое слово new для создания объекта класса String, где в качестве new используется для создания объектов для других классов.

Я слышал о классах Wrapper, подобных Integer, Double, которые похожи на это. Но String не Wrapper, не так ли?

Собственно, что происходит, когда я использую

     String message = "Hai";

?? Как он отличается от

String message = new String("Hai");

Здесь message ссылочная переменная или что-то еще? Существуют ли другие классы, для которых не требуется new для создания объекта?

4b9b3361

Ответ 1

В следующей строке вы не создаете новый объект String в куче, а повторно используете строковый литерал (если он уже доступен):

String message = "Hai";

"Hai" - строковый литерал в пуле строковых литералов. Поскольку строки являются неизменяемыми, они могут использоваться повторно, поэтому они объединены в пул строковых литералов JVM. И это рекомендуется, потому что вы повторно используете его.

Но при этом вы фактически создаете новый объект (в куче):

String message = new String("Hai");

new String("Hai") - новый объект String. В этом случае, даже если литерал "Hai" уже был в пуле строковых литералов, создается новый объект. Это не рекомендуется, потому что есть вероятность, что вы можете завершить несколько объектов String с тем же значением.

Также см. этот пост: Вопросы о пуле строк Java

Существуют ли другие классы, которые не требуют нового для создания объекта?

На самом деле вы не можете создать какой-либо объект в Java без использования ключевого слова new.

например.

Integer i = 1;

Не означает, что объект Integer создается без использования new. Для нас просто не требуется явно использовать ключевое слово new. Но под капотом, если объект Integer со значением 1 еще не существует в кеше (Integer объекты кэшируются JVM), для его создания будет использовано ключевое слово new.

Ответ 2

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

Строковые литералы все интернированы, что означает, что они являются постоянными значениями, хранящимися во время выполнения Java, и могут использоваться для разных классов. Например:

class MainClass (
    public String test = "hello";
}

class OtherClass {
   public String another = "hello";

   public OtherClass() {
       MainClass main = new MainClass();
       System.out.println(main.test == another);
   }
}

Выведет "true", поскольку оба экземпляра String фактически указывают на один и тот же объект. Это не так, если вы инициализируете строки с помощью нового ключевого слова.

Ответ 3

Строковые и целые создания разные.

String s = "Test";

Здесь оператор '=' перегружен для строки. Так что оператор "+" в "некоторых" + "вещах". Где как,

Integer i = 2;

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

String h1 = "hi";

будет отличаться от

String h2 = new String("hi");

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

Но когда вы явно создаете строковый объект, будет создан новый объект, например, его адрес равен 2000. Теперь новый объект укажет на запись в таблице строк, которая равна 1000.

Следовательно, когда вы говорите

h1 == h2

он сравнивает

1000 == 2000

Так что это ложь

Ответ 4

В java
"==" сравнивает местоположения памяти левой и правой сторон (а не значение в этой ячейке памяти), и поэтому в случае

new String("hai")==new String("hai")

возвращает false.

В случае "Hai" == "Hai" java не выделяет отдельную память для того же строкового литерала, поэтому здесь "==" возвращает true. Вы всегда можете использовать метод equals для сравнения значений.