Java에서 final로 선언된 문자열과 == 비교
자바 문자열에 대한 간단한 질문이 있습니다.는 두 한 다음 이 합니다.==
.
String str1="str";
String str2="ing";
String concat=str1+str2;
System.out.println(concat=="string");
「」concat=="string"
false
는 백백의 한다)equals()
★★★★★★★★★★★★★★★★★」==
를 참조해 주세요.
되었을 때final
같이
final String str1="str";
final String str2="ing";
String concat=str1+str2;
System.out.println(concat=="string");
「」concat=="string"
반환됩니다.true
?는 final
화를를가?가 져??그게 인인 이이 풀? ?? ??? 니면면 그가? 가? ???
「 」를 선언했을 String
(불변의) 변하기 쉬운final
컴파일 시간 상수식을 사용하여 초기화하면 컴파일 시간 상수식도 되고 값이 사용되는 컴파일러에 의해 입력됩니다.따라서 두 번째 코드 예제에서는 값을 삽입한 후 문자열 연결은 컴파일러에 의해 다음과 같이 변환됩니다.
String concat = "str" + "ing"; // which then becomes `String concat = "string";`
★★★★★★★★★★★와 비교하면"string"
드립니다.true
스트링 리터럴은 내장되어 있기 때문입니다.
String
, 「」, 「」final
컴파일 시간 상수식(θ15.28)으로 초기화된 것을 상수 변수라고 합니다.
" " " 의 컴파일
String
는 항상 고유한 인스턴스를 공유하기 위해 메서드를 사용하여 "interned"됩니다.
.String
.final
따라서 컴파일 시간 상수 표현식이 아닙니다. 조작은됩니다.String
코드의수.이를 확인하려면 두 코드의 바이트 코드를 비교합니다.
첫 번째 코드 예제(비버전final
)는 다음 바이트 코드로 컴파일됩니다.
Code:
0: ldc #2; //String str
2: astore_1
3: ldc #3; //String ing
5: astore_2
6: new #4; //class java/lang/StringBuilder
9: dup
10: invokespecial #5; //Method java/lang/StringBuilder."<init>":()V
13: aload_1
14: invokevirtual #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
17: aload_2
18: invokevirtual #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
21: invokevirtual #7; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
24: astore_3
25: getstatic #8; //Field java/lang/System.out:Ljava/io/PrintStream;
28: aload_3
29: ldc #9; //String string
31: if_acmpne 38
34: iconst_1
35: goto 39
38: iconst_0
39: invokevirtual #10; //Method java/io/PrintStream.println:(Z)V
42: return
그것은 보관하고 .str
★★★★★★★★★★★★★★★★★」ing
변수로, 「」를 사용하고, 「」를 사용합니다.StringBuilder
연결 작업을 수행합니다.
한편, 두 번째 코드 예(final
버전)는 다음과 같습니다.
Code:
0: ldc #2; //String string
2: astore_3
3: getstatic #3; //Field java/lang/System.out:Ljava/io/PrintStream;
6: aload_3
7: ldc #2; //String string
9: if_acmpne 16
12: iconst_1
13: goto 17
16: iconst_0
17: invokevirtual #4; //Method java/io/PrintStream.println:(Z)V
20: return
최종 변수를 직접 삽입하여 String String을 .string
「」에 로드됩니다.ldc
에서의 0
그런 다음 두 번째 문자열 리터럴이 로딩됩니다.ldc
에서의 7
.String
"컴파일 내부 처리가 있습니다.String은 컴파일 시에 이미 알려져 있으며 내부 처리되어 있습니다.
로는, 가가조 as as as as as as as as as as as as as,final String
자바에 수용되어 있습니다.다음 중 하나:
따라서 == 또는 !=를 사용하여 두 String을 비교해야 할 경우 비교하기 전에 String.intern() 메서드를 호출해야 합니다.그렇지 않은 경우 String 비교에는 항상 String.equals(String)를 선호합니다.
''에게 전화하면String.intern()
두 할 수 요.==
하지만 여기서는String.intern()
final String
부부수수수수있있있있
String.intern() 메서드에 대한 == 연산자와 Javadoc을 사용하여 String 비교에 대한 자세한 내용을 확인할 수 있습니다.
상세한 것에 대하여는, 이 Stackoverflow 의 투고도 참조해 주세요.
이 방법을 보면
public void noFinal() {
String str1 = "str";
String str2 = "ing";
String concat = str1 + str2;
System.out.println(concat == "string");
}
public void withFinal() {
final String str1 = "str";
final String str2 = "ing";
String concat = str1 + str2;
System.out.println(concat == "string");
}
그리고 그것은 로 분해되었다.javap -c ClassWithTheseMethods
되는
public void noFinal();
Code:
0: ldc #15 // String str
2: astore_1
3: ldc #17 // String ing
5: astore_2
6: new #19 // class java/lang/StringBuilder
9: dup
10: aload_1
11: invokestatic #21 // Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String;
14: invokespecial #27 // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
17: aload_2
18: invokevirtual #30 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
21: invokevirtual #34 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
...
그리고.
public void withFinal();
Code:
0: ldc #15 // String str
2: astore_1
3: ldc #17 // String ing
5: astore_2
6: ldc #44 // String string
8: astore_3
...
Strings가 Strings를 사용해야 .StringBuilder
str1
★★★★★★★★★★★★★★★★★」str2
String concat=str1+str2;
로 컴파일 됩니다.
String concat = new StringBuilder(str1).append(str2).toString();
은 즉, ,,concat
스트링 스트링
스트링이 최종적인 스트링이 변경되지 가정할 수 .StringBuilder
을 안전하게 할 수 때문에, 그 값을 사용할 수 있습니다.
String concat = str1 + str2;
로 변경할 수 있다
String concat = "str" + "ing";
에 연결되었습니다.
String concat = "string";
은 즉, ,,concate
된 후 스팅 내의 풀의 됩니다.if
★★★★★★ 。
및 에 풀 컨셉이 포함되어 있습니다.
이번에는 이 글자의 를 한 번 볼까요?final
Compiled from "Main.java"
public class Main {
public Main();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]) throws java.lang.Exception;
Code:
0: ldc #2 // String string
2: astore_3
3: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
6: aload_3
7: ldc #2 // String string
9: if_acmpne 16
12: iconst_1
13: goto 17
16: iconst_0
17: invokevirtual #4 // Method java/io/PrintStream.println:(Z)V
20: return
}
0:
★★★★★★★★★★★★★★★★★」2:
, . . . . . . . .String
"string"
는 ( 로컬 ( 「」)에 됩니다.concat
가 작성(연결)하고 있다고 할 수 .String
"string"
컴파일할 때 그 자체입니다.
(非) (비(非)'final
Compiled from "Main2.java"
public class Main2 {
public Main2();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]) throws java.lang.Exception;
Code:
0: ldc #2 // String str
2: astore_1
3: ldc #3 // String ing
5: astore_2
6: new #4 // class java/lang/StringBuilder
9: dup
10: invokespecial #5 // Method java/lang/StringBuilder."<init>":()V
13: aload_1
14: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/Stri
ngBuilder;
17: aload_2
18: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/Stri
ngBuilder;
21: invokevirtual #7 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
24: astore_3
25: getstatic #8 // Field java/lang/System.out:Ljava/io/PrintStream;
28: aload_3
29: ldc #9 // String string
31: if_acmpne 38
34: iconst_1
35: goto 39
38: iconst_0
39: invokevirtual #10 // Method java/io/PrintStream.println:(Z)V
42: return
}
두 개 요.String
수,"str"
★★★★★★★★★★★★★★★★★」"ing"
시 .StringBuilder
.
단, Java의 String 리터럴 표기법을 사용하여 작성하면 해당 개체가 아직 풀에 존재하지 않는 한 자동으로 intern() 메서드를 호출하여 String 풀에 넣습니다.
결승전이 왜 다른가요?
컴파일러는 최종 변수가 변경되지 않는다는 것을 알고 있습니다.이러한 최종 변수를 추가하면 출력은 String Pool로 이동합니다.str1 + str2
식 출력 또한 절대 변경되지 않습니다. 그래서 마지막으로 컴파일러는 위의 두 최종 변수의 출력 후에 inter method를 호출합니다.최종 변수 컴파일러가 아닌 경우에는 intern 메서드를 호출하지 마십시오.
언급URL : https://stackoverflow.com/questions/19418427/comparing-strings-with-which-are-declared-final-in-java
'programing' 카테고리의 다른 글
MariaDB: ALTER TABLE 구문을 사용하여 외부 키를 추가하시겠습니까? (0) | 2022.09.08 |
---|---|
i++는 스레드가 안전하지 않다고 들었는데, ++i 스레드는 안전한가요? (0) | 2022.09.02 |
고정 길이 데이터 유형(C/C++) (0) | 2022.09.02 |
Maven Integration 테스트를 실행하려면 어떻게 해야 합니까? (0) | 2022.09.02 |
NullPointer자바에 StackTrace과 예외. (0) | 2022.09.02 |