"오래된"방식은 StringBuilder
일련 의 지향적 인 작업을 출력 합니다. 이 프로그램을 고려하십시오.
public class Example {
public static void main(String[] args)
{
String result = args[0] + "-" + args[1] + "-" + args[2];
System.out.println(result);
}
}
JDK 8 또는 이전 버전으로 컴파일 한 다음 사용 javap -c Example
하여 바이트 코드를 보면 다음과 같은 내용이 표시됩니다.
공용 클래스 예 {
공개 예제 ();
암호:
0 : aload_0
1 : invokespecial # 1 // 메소드 java / lang / Object. "<init>":() V
4 : 반환
public static void main (java.lang.String []);
암호:
0 : 새로운 # 2 // 클래스 java / lang / StringBuilder
3 : 복제
4 : invokespecial # 3 // 메소드 java / lang / StringBuilder. "<init>":() V
7 : aload_0
8 : 아이콘 t_0
9 : aaload
10 : invokevirtual # 4 // 메소드 java / lang / StringBuilder.append : (Ljava / lang / String;) Ljava / lang / StringBuilder;
13 : ldc # 5 // 문자열-
15 : invokevirtual # 4 // 메소드 java / lang / StringBuilder.append : (Ljava / lang / String;) Ljava / lang / StringBuilder;
18 : aload_0
19 : iconst_1
20 : aaload
21 : invokevirtual # 4 // 메소드 java / lang / StringBuilder.append : (Ljava / lang / String;) Ljava / lang / StringBuilder;
24 : ldc # 5 // 문자열-
26 : invokevirtual # 4 // 메소드 java / lang / StringBuilder.append : (Ljava / lang / String;) Ljava / lang / StringBuilder;
29 : aload_0
30 : iconst_2
31 : aaload
32 : invokevirtual # 4 // 메소드 java / lang / StringBuilder.append : (Ljava / lang / String;) Ljava / lang / StringBuilder;
35 : invokevirtual # 6 // 메소드 java / lang / StringBuilder.toString :() Ljava / lang / String;
38 : astore_1
39 : getstatic # 7 // 필드 java / lang / System.out : Ljava / io / PrintStream;
42 : aload_1
43 : invokevirtual # 8 // 메소드 java / io / PrintStream.println : (Ljava / lang / String;) V
46 : 반환
}
당신이 볼 수 있듯이, 그것은 생성 StringBuilder
및 사용을 append
. 내장 버퍼의 기본 용량이 StringBuilder
16 자에 불과하기 때문에 이것은 상당히 비효율적 인 것으로 유명 하며 컴파일러 가 미리 더 많은 할당을 알 수 있는 방법이 없으므로 결국 재 할당해야합니다. 또한 많은 메서드 호출입니다. (JVM은 때때로 이러한 호출 패턴을 감지하고 다시 작성하여 더 효율적으로 만들 수 있습니다.)
Java 9가 생성하는 것을 살펴 보겠습니다.
공용 클래스 예 {
공개 예제 ();
암호:
0 : aload_0
1 : invokespecial # 1 // 메소드 java / lang / Object. "<init>":() V
4 : 반환
public static void main (java.lang.String []);
암호:
0 : aload_0
1 : 아이콘
2 : aaload
3 : aload_0
4 : iconst_1
5 : aaload
6 : aload_0
7 : iconst_2
8 : aaload
9 : invokedynamic # 2, 0 // InvokeDynamic # 0 : makeConcatWithConstants : (Ljava / lang / String; Ljava / lang / String; Ljava / lang / String;) Ljava / lang / String;
14 : astore_1
15 : getstatic # 3 // 필드 java / lang / System.out : Ljava / io / PrintStream;
18 : aload_1
19 : invokevirtual # 4 // 메소드 java / io / PrintStream.println : (Ljava / lang / String;) V
22 : 반환
}
오,하지만 더 짧습니다. :-) makeConcatWithConstants
from에 대한 단일 호출을 수행 StringConcatFactory
하며 Javadoc에 다음과 같이 표시됩니다.
유형 적응 및 인수의 부분 평가 후에 알려진 유형의 알려진 수의 인수를 효율적으로 연결하는 데 사용할 수있는 문자열 연결 메서드의 생성을 용이하게하는 메서드입니다. 이러한 메소드는 일반적으로 Java 프로그래밍 언어 의 문자열 연결 기능 을 지원 하기 위해 invokedynamic
호출 사이트의 부트 스트랩 메소드 로 사용됩니다 .