Programing

Java의 일부 문자열에 대해 참조 비교 (==)가 작동하는 이유는 무엇입니까?

crosscheck 2020. 12. 4. 07:54
반응형

Java의 일부 문자열에 대해 참조 비교 (==)가 작동하는 이유는 무엇입니까?


String을 비교하기 위해 다음 코드 줄이 있습니다. str1은 str2와 같지 않습니다. 객체 참조를 비교하기 때문에 이해할 수 있습니다. 그런데 왜 s1이 s2와 같습니까?

String s1 = "abc";
String s2 = "abc";

String str1 = new String("abc");
String str2 = new String("abc");

if (s1==s2)
    System.out.println("s1==s2");           
else
    System.out.println("s1!=s2");

if (str1==str2)
    System.out.println("str1==str2");           
else
    System.out.println("str1!=str2");

if (s1==str1)
    System.out.println("str1==s1");         
else
    System.out.println("str1!=s1");

산출:

  s1==s2
  str1!=str2
  str1!=s1 

문자열 상수 풀은 기본적으로 모든 문자열 리터럴을 캐시하므로 아래에 동일한 객체가 있으므로 s1==s2. 리터럴이 선언 될 때마다 새 문자열 개체를 만드는 것을 방지하는 것은 본질적으로 VM의 최적화이며, 이는 매우 빠르게 비용이 많이들 수 있습니다! 당신과 함께 str1==str2예를 들어, 당신은 명시 적으로 거짓 따라서 왜 새 문자열 객체를 생성하기 위해 VM을 말하는 것입니다.

제쳐두고, intern()어떤 문자열 에서 메서드를 호출하면 상수 풀에 추가됩니다 (그리고 풀에 추가 된 문자열을 반환합니다.)하지만 처리 중인지 확실하지 않은 한 반드시이 작업을 수행하는 것은 좋은 생각은 아닙니다. 확실히 상수로 사용될 문자열. 그렇지 않으면 메모리 누수를 추적하기 어렵게 만들 수 있습니다.


s1 및 s2는 문자열 리터럴입니다. 새 문자열 리터럴을 만들 때 컴파일러는 먼저 동일한 것을 나타내는 리터럴이 문자열 풀에 있는지 여부를 확인합니다. 존재하는 경우 컴파일러는 해당 리터럴을 반환하고 그렇지 않은 경우 컴파일러는 새 리터럴을 만듭니다.

String을 만들면 s2컴파일러는 s1이전에 이미 생성 된 풀 에서 String 반환합니다 . 그것이 이유 s1s2동일합니다. 이 동작을 인턴 이라고 합니다.


이 현상은 String interning 때문 입니다.

기본적으로 모든 문자열 리터럴은 "캐시"되고 재사용됩니다.


이는 문자열 리터럴이 인턴되기 때문입니다. 이 문제에 대해 Java 문서 는 다음과 같이 말합니다.

모든 리터럴 문자열 및 문자열 값 상수식이 인턴됩니다.

그리고 이것은 이유 s1s2동일한 이유를 설명합니다 (이 두 변수는 동일한 인턴 문자열을 가리킴)


Java에서는 동일한 상수 문자열이 재사용됩니다. 그래서 그 s1s2같은 "ABC"개체를 가리킨 s1==s2. 그러나을 사용 new String("abc")하면 다른 개체가 생성됩니다. 그래서 s1 != str1.


stringJava에서 변경 불가능한 것처럼 모든 string literals것은 재사용을 위해 캐시됩니다.

new () 연산자를 사용하여 String 객체를 만들 때 항상 힙 메모리에 새 객체를 만듭니다. 반면에 "Java"와 같은 문자열 리터럴 구문을 사용하여 객체를 생성하면 문자열 풀 (최근 Java 릴리스에서 힙 공간으로 이동 한 Perm gen 공간의 String 객체 캐시)에서 기존 객체를 반환 할 수 있습니다. , 이미있는 경우. 그렇지 않으면 새 문자열 개체를 만들고 나중에 다시 사용할 수 있도록 문자열 풀에 넣습니다.

String s1 = new String("java");
String s2 = new String("java");
String s3 = "java";
String s4 = "java";

여기에 이미지 설명 입력

이 링크를 참조하십시오

참고 URL : https://stackoverflow.com/questions/9698260/what-makes-reference-comparison-work-for-some-strings-in-java

반응형