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를 사용해야 .StringBuilderstr1 ★★★★★★★★★★★★★★★★★」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 |