Конкатенация строк и autoboxing в Java
Когда вы соединяете строку с примитивом, таким как int, делает ли это autobox значение первым.
Исх.
String string = "Four" + 4;
Как он преобразует значение в строку в Java ?
3 ответа:
Чтобы увидеть, что производит компилятор Java, всегда полезно использовать
javap -c
, чтобы показать фактический байт-код, произведенный:Например, следующий код Java:
String s1 = "Four" + 4; int i = 4; String s2 = "Four" + i;
Выдаст следующий байт-код:
0: ldc #2; //String Four4 2: astore_1 3: iconst_4 4: istore_2 5: new #3; //class java/lang/StringBuilder 8: dup 9: invokespecial #4; //Method java/lang/StringBuilder."<init>":()V 12: ldc #5; //String Four 14: invokevirtual #6; //Method java/lang/StringBuilder.append:(Ljava/lang/ String;)Ljava/lang/StringBuilder; 17: iload_2 18: invokevirtual #7; //Method java/lang/StringBuilder.append:(I)Ljava/lan g/StringBuilder; 21: invokevirtual #8; //Method java/lang/StringBuilder.toString:()Ljava/la ng/String; 24: astore_3 25: return
Отсюда мы можем видеть:
- в случае
"Four" + 4
компилятор Java (я использовал JDK 6) был достаточно умен, чтобы вывести, что это константа, поэтому нет вычислительных усилий во время выполнения, поскольку строка сцепляется при компиляции время- в случае
"Four" + i
эквивалентным кодом являетсяnew StringBuilder().append("Four").append(i).toString()
- Автобоксинг здесь не участвует, так как есть StringBuilder.метод append (int), который, согласно документам, использует строку .valueOf (int) для создания строкового представления целого числа.
Компилятор java фактически создает
StringBuilder
1 и вызывает методappend()
. Это можно увидеть в байт-коде:22 invokespecial java.lang.StringBuilder(java.lang.String) [40] ... 29 invokevirtual java.lang.StringBuilder.append(int) : java.lang.StringBuilder [47] 32 invokevirtual java.lang.StringBuilder.toString() : java.lang.String [51]
Тем не менее, поведение идентично боксу, а затем вызову
toString()
:"Four" + new Integer(4).toString()
- и я верю, что разработчики языка имели в виду именно это.
(1) если быть точным, компилятор уже объединяет строковый литерал и литерал int в один строковый литерал
"Four4"
. Вы можете увидеть это в байт-коде на следующем рисунке строка в байт-коде:0 ldc <String "Four4"> [19]
Согласно http://jcp.org/aboutJava/communityprocess/jsr/tiger/autoboxing.html , автобоксинг выполняется на примитивном типе всякий раз, когда требуется ссылочный тип (например, класс Integer в этом случае)
Таким образом, int преобразуется в целое число, после чего вызывается метод integer objects toString() и его результат добавляется к предыдущей строке.