programing

Java에서 final로 선언된 문자열과 == 비교

kingscode 2022. 9. 2. 00:07
반응형

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스트링 리터럴은 내장되어 있기 때문입니다.

JLS © 4.12.4 - 변수:

String, 「」, 「」final컴파일 시간 상수식(θ15.28)으로 초기화된 것을 상수 변수라고 합니다.

또한 JLS © 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

반응형