Вы действительно понимаете строку? (пересмотренный вариант)

Java

До коррекции: новый объект будет хранить реальное значение в куче;Большая ошибка! ! ! !

После исправления: новый объект, куча хранит не реальное значение, а адрес строковой константы в пуле констант.

1. Бросать кирпичи, чтобы привлечь нефрит

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

public class StringTest {
    public static void main(String[] args) {
        String str1 = "hello";
        String str2 = "hello";
        String str3 = "he" + "ll" + "o";
        System.out.println(str1 == str2);
        System.out.println(str1 == str3);

        String str = "o";
        String str4 = "hell" + str;
        System.out.println(str1 == str4);

        String str5 = new String("hello");
        System.out.println(str1 == str5);
        System.out.println(str4 == str5);
        System.out.println(str1.equals(str5));
        //intern()函数作用:直接获取常量池中字符串常量的地址并返回。
        System.out.println(str1==str5.intern());

        String str6 = new String("beyond");

    }
}

//输出的结果
//true
//true
//false
//false
//false
//true
//true

Вы поняли это правильно?

Во-вторых, разработать принцип

1: Кратко объясните разницу между == и equals():

  • ==: Сравнение заключается в том, совпадают ли адреса памяти, то есть указывает ли ссылка на один и тот же объект в памяти. Значение true, если оно указывает на тот же адрес памяти, в противном случае — значение false.
  • equals(): сравнивает, совпадают ли значения, на которые указывают две ссылки. Возвращает true, если указанные значения совпадают, в противном случае возвращает false.

2: Подробно расскажите о String с точки зрения памяти.

Прежде всего, нам нужно знать, что String — это класс в Java, и есть два способа создания объектов [независимо от отражения, клонирования и десериализации].

  • Способ 1: Строка str1 = "привет";поместить объект в постоянный пул
  • Способ 2: String str2 = new String("hello");Создал объект в куче
1554981844054
1554981844054

(Моя фотография такая уродливая... [встает на руки])

проходитьметод первыйСоздайте объект String,Сначала проверьте постоянный пулЕсть ли в нем эта строковая константа, если она есть, прямо указать ссылку на эту константу (то есть в примере: str1==str2 верно). Тем более загадочными будут str3, str4. Поскольку str3 состоит из строковых констант "he", "ll" и "o", компилятор обнаруживает, что строковые константы, составленные из этих трех констант, уже существуют в пуле констант, то есть окончательное значение было определено во время компиляции. , то он также укажет ссылку на строковую константу «hello». Для str4, поскольку компилятор не может определить окончательное значение строки во время компиляции, он сохранит строковую константу «ад» в пуле констант, а затем сгенерирует конечный объект в куче [продлить его: Объединяйте строки через «+», а нижний слой сращивается с помощью метода append() из new StringBuilder(), поэтому вам следует избегать использования «+» для сращивания строк в цикле, чтобы избежать создания большого количества мусора объекты].

проходитьСпособ 2И создайте объект String,Сначала проверьте, существует ли строковая константа в пуле констант., если он существует, то новый объект будет создан непосредственно в памяти, иначе сначала в пуле констант будет сгенерирована строковая константа, а затем в куче (str6 на рисунке) будет сгенерирован новый объект.Особое внимание: (Значением нового объекта является адрес строковой константы в пуле констант, то есть адрес, хранящийся в куче, является строковой константой)

3: Используйте команду javap для проверки результатов компиляции.

​ javap — это инструмент для защиты от синтаксического анализа, который поставляется с jdk. Его функция состоит в де-анализе области кода (инструкции по сборке), таблицы локальных переменных, таблицы исключений, таблицы отображения смещения строки кода, пула констант и другой информации, соответствующей текущему классу, в соответствии с файлом байт-кода класса.

Формат использования javap:
javap <options> <classes>
Где классы - это файл класса, который вы хотите декомпилировать.
Введите javap или javap -help непосредственно в командной строке, чтобы увидеть, что параметры javap имеют следующие параметры:

-help  --help  -?        输出此用法消息
 -version                 版本信息,其实是当前javap所在jdk的版本信息,不是class在哪个jdk下生成的。
 -v  -verbose             输出附加信息(包括行号、本地变量表,反汇编等详细信息)
 -l                         输出行号和本地变量表
 -public                    仅显示公共类和成员
 -protected               显示受保护的/公共类和成员
 -package                 显示程序包/受保护的/公共类 和成员 (默认)
 -p  -private             显示所有类和成员
 -c                       对代码进行反汇编
 -s                       输出内部类型签名
 -sysinfo                 显示正在处理的类的系统信息 (路径, 大小, 日期, MD5 散列)
 -constants               显示静态最终常量
 -classpath <path>        指定查找用户类文件的位置
 -bootclasspath <path>    覆盖引导类文件的位置

Например, этот пример: javap -verbose StringTest

1554891308064
1554891308064

3. Резюме

Строка существует в памяти в двух формах, если вы передаетепрямое назначениеФорма (первый метод) преобразует объект напрямуюв постоянный пулMedium [Если склеивается из нескольких строковых констант, а окончательный результат определяется во время компиляции (то есть в пуле констант есть финальная сплайсированная строка), прямо указывайте ссылку на эту строковую константу; если in Конечный результат не может быть определен во время компиляции, конечный результат будет сгенерирован в куче, а содержащиеся в нем строковые константы будут существовать в пуле констант]; если передаетсяновый способ(Способ 2),Сначала сгенерируйте строковую константу в пуле констант, а затем сгенерируйте строковый объект в куче.Значением объекта является адрес строковой константы в пуле констант.

Младший брат невежественный и невежественный.Если есть какая-то ошибка, пожалуйста, поправьте меня, большое спасибо.