предисловие
Насколько я знаю, строки действительно стали наиболее часто используемым классом для Java-разработчиков, и они используются очень часто. Все мы знаем, что String на самом деле инкапсулирует символы, поэтому соединение двух строк заключается в соединении символов в строковом объекте. Многие люди привыкли использовать+
Чтобы объединить строки, некоторые люди будут использовать StringBuilder.append
метод.
"+" после компиляции
Посмотрим, используем ли мы его прямо в программе+
Чтобы соединить строки, используйте следующий простой пример для иллюстрации, выполните две операции конкатенации строк, а именноs3 = s1 + s2
.
public class TestString {
public static void main(String[] args) {
String s1 = "www";
String s2 = "ccc";
String s3 = s1 + s2;
}
}
тогдаjavap -c TestString.class
Глядя на ситуацию после компиляции, вы можете увидеть, что компилятор на самом деле правильный+
После преобразования он преобразуется в объект StringBuilder для работы, сначала используйте S1, чтобы создать объект StringBuilder, а затем использоватьappend
способ подключения s2 и, наконец, вызоваtoString
метод завершен.
public class com.seaboat.string.TestString {
public com.seaboat.string.TestString();
Code:
0: aload_0
1: invokespecial #8 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: ldc #16 // String www
2: astore_1
3: ldc #18 // String ccc
5: astore_2
6: new #20 // class java/lang/StringBuilder
9: dup
10: aload_1
11: invokestatic #22 // Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String;
14: invokespecial #28 // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
17: aload_2
18: invokevirtual #31 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
21: invokevirtual #35 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
24: astore_3
25: return
}
Является ли «+» эквивалентом «добавлять»?
можно увидеть впереди+
Под действием компилятора он будет преобразован в StringBuilderappend
выполнение метода, поэтому, если отбросить эффективность работы, они на самом деле одинаковы.
Означает ли одинаковая природа, что они эквивалентны? Или его можно использовать напрямую для удобства?+
объединить строки и оставить остальное компилятору? Продолжайте смотреть пример, в этом примере есть цикл for для конкатенации строк.
public class TestString2 {
public static void main(String[] args) {
String s = "www";
for (int i = 0; i < 10; i++)
s += i;
}
}
Ситуация после компиляции следующая, не беда, если вы не знакомы с инструкцией, смотрим только важные части,if_icmplt 8
, это условное суждение цикла for.Если оно меньше 10, он продолжит переход к позиции 8. После 8 фактически создается объект StringBuilder, и объект инициализируется значением локального переменная s, а затем устанавливается локальная переменная i.append
в объект StringBuilder и, наконец, вызовитеtoString
Метод сохраняет полученное значение в локальной переменной s.
Таким образом, объект StringBuilder создается каждый раз в цикле и выполняется вызовtoString
очевидно, что такая эффективность выполнения относительно низка, и это увеличивает нагрузку на сборщик мусора.
public class com.seaboat.string.TestString2 {
public com.seaboat.string.TestString2();
Code:
0: aload_0
1: invokespecial #8 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: ldc #16 // String www
2: astore_1
3: iconst_0
4: istore_2
5: goto 30
8: new #18 // class java/lang/StringBuilder
11: dup
12: aload_1
13: invokestatic #20 // Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String;
16: invokespecial #26 // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
19: iload_2
20: invokevirtual #29 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
23: invokevirtual #33 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
26: astore_1
27: iinc 2, 1
30: iload_2
31: bipush 10
33: if_icmplt 8
36: return
}
дружеское письмо
Оставлять все компилятору недружелюбно, для того, чтобы программа выполнялась более эффективно, нам лучше всего самим управлять экземпляром StringBuilder, например, мы создаем только один экземпляр StringBuilder и используем его позже.append
Строка подключения метода.
public class TestString3 {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder("www");
for (int i = 0; i < 10; i++)
sb.append(i);
}
}
Скомпилированная ситуация выглядит следующим образом: сначала создайте объект StringBuilder, создайте экземпляр объекта со строкой «www», а затем вызовите его в цикле.append
Метод добавляет локальную переменную i к объекту StringBuilder.
public class com.seaboat.string.TestString3 {
public com.seaboat.string.TestString3();
Code:
0: aload_0
1: invokespecial #8 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: new #16 // class java/lang/StringBuilder
3: dup
4: ldc #18 // String www
6: invokespecial #20 // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
9: astore_1
10: iconst_0
11: istore_2
12: goto 24
15: aload_1
16: iload_2
17: invokevirtual #23 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
20: pop
21: iinc 2, 1
24: iload_2
25: bipush 10
27: if_icmplt 15
30: return
}
------------- Рекомендуем прочитать ------------
Резюме моей статьи за 2017 год — машинное обучение
Краткое изложение моих статей за 2017 год — Java и промежуточное ПО
Резюме моих статей 2017 года — глубокое обучение
Краткое изложение моих статей за 2017 год — исходный код JDK
Резюме моей статьи за 2017 год — обработка естественного языка
Резюме моих статей 2017 года — Java Concurrency
Поговори со мной, задай мне вопросы:
Меню официальной учетной записи было разделено на «Сводка для чтения», «Распределенное», «Машинное обучение», «Глубокое обучение», «НЛП», «Глубина Java», «Ядро параллелизма Java», «Исходный код JDK», "Tomcat Core" "Подождите, может быть, есть тот, который соответствует вашему аппетиту.
Зачем писать «Анализ проектирования ядра Tomcat»
Добро пожаловать, чтобы следовать: