code

Java의 문자열 풀이 란 무엇입니까?

codestyles 2020. 11. 16. 08:20
반응형

Java의 문자열 풀이 란 무엇입니까?


Java의 StringPool에 대해 혼란 스럽습니다. Java에서 String 장을 읽으면서 이것을 보았습니다. 평신도 용어로 StringPool이 실제로 무엇을하는지 이해하도록 도와주세요.


이것은 true(우리가 equals방법을 사용하지 않더라도 : 문자열을 비교하는 올바른 방법)

    String s = "a" + "bc";
    String t = "ab" + "c";
    System.out.println(s == t);

컴파일러가 문자열 리터럴을 최적화 할 때, 모두 있음을보고 s하고 t같은 값을 가지고 있으며, 따라서 당신은 단지 하나의 문자열 개체가 필요합니다. StringJava에서는 변경할 수 없기 때문에 안전 합니다.
그 결과, 모두 st포인트 같은 객체 및 저장 일부 작은 메모리.

이름 '문자열 풀'은 이미 정의 된 모든 문자열이 일부 '풀'에 저장되고 새 String개체 컴파일러 를 만들기 전에 해당 문자열이 이미 정의되어 있는지 확인 한다는 생각에서 비롯 됩니다.


나는 그것이 실제로 많은 일을한다고 생각하지 않는다. 그것은 단지 문자열 리터럴을위한 캐시 인 것처럼 보인다. 값이 동일한 문자열이 여러 개있는 경우 모두 문자열 풀에서 동일한 문자열 리터럴을 가리 킵니다.

String s1 = "Arul"; //case 1 
String s2 = "Arul"; //case 2 

1의 경우 리터럴 s1이 새로 생성되어 풀에 보관됩니다. 그러나 경우 2, 리터럴 s2는 s1을 참조하며 대신 새 항목을 생성하지 않습니다.

if(s1 == s2) System.out.println("equal"); //Prints equal. 

String n1 = new String("Arul"); 
String n2 = new String("Arul"); 
if(n1 == n2) System.out.println("equal"); //No output.  

http://p2p.wrox.com/java-espanol/29312-string-pooling.html


가상 머신 사양의 견적부터 시작하겠습니다.

String 리터럴이 포함 된 클래스 또는 인터페이스를로드하면 해당 리터럴을 나타내는 새 String 개체 (§2.4.8)가 생성 될 수 있습니다. 이는 해당 리터럴의 이전 발생을 나타 내기 위해 String 객체가 이미 생성되었거나 리터럴과 동일한 문자열을 나타내는 String 객체에서 String.intern 메서드가 호출 된 경우에는 발생하지 않을 수 있습니다.

이것은 발생하지 않을 수 있습니다 -이것은 String객체에 특별한 무언가가 있다는 힌트 입니다. 일반적으로 생성자를 호출하면 항상 클래스의 새 인스턴스가 생성 됩니다 . 특히 String 객체가 리터럴로 '생성'된 경우에는 Strings의 경우가 아닙니다. 이러한 문자열은 전역 저장소 (풀)에 저장되거나 적어도 참조는 풀에 보관되며 이미 알려진 문자열의 새 인스턴스가 필요할 때마다 vm은 풀에서 개체에 대한 참조를 반환합니다. 의사 코드에서는 다음과 같이 될 수 있습니다.

1: a := "one" 
   --> if(pool[hash("one")] == null)  // true
           pool[hash("one") --> "one"]
       return pool[hash("one")]

2: b := "one" 
  --> if(pool[hash("one")] == null)   // false, "one" already in pool
        pool[hash("one") --> "one"]
      return pool[hash("one")] 

따라서이 경우 변수 a동일한 객체에 b대한 참조를 보유 합니다. 이 경우 .(a == b) && (a.equals(b)) == true

생성자를 사용하는 경우에는 그렇지 않습니다.

1: a := "one"
2: b := new String("one")

다시 "one"풀에 생성되었지만 동일한 리터럴에서 새 인스턴스를 생성합니다.이 경우에는(a == b) && (a.equals(b)) == false

그렇다면 우리는 문자열 풀을 가지고 있습니까? 문자열, 특히 문자열 리터럴은 일반적인 Java 코드에서 널리 사용됩니다. 그리고 그들은 불변입니다. 그리고 메모리를 절약하고 성능을 높이기 위해 String을 캐시 할 수 있습니다 (생성 노력 감소, 수집 할 가비지 감소).

프로그래머로서 우리는 염두에 두는 한 문자열 풀에 대해별로 신경을 쓸 필요가 없습니다.

  • (a == b) && (a.equals(b))수 있습니다 true또는 false( 항상 사용하는 equals문자열 비교)
  • 리플렉션을 사용 char[]하여 문자열 의 뒷받침을 변경하지 마십시오 (누가 해당 문자열을 사용하고 있는지 알 수 없으므로)

JVM이 클래스를로드하거나 그렇지 않으면 리터럴 문자열 또는 일부 코드 internsa 문자열을 볼 때 이러한 각 문자열의 복사본이 하나있는 대부분 숨겨진 조회 테이블에 문자열을 추가합니다. 다른 복사본이 추가되면 런타임에서 모든 리터럴이 동일한 문자열 개체를 참조하도록 정렬합니다. 이것을 "인턴"이라고합니다. 다음과 같이 말하면

String s = "test";
return (s == "test");

true첫 번째와 두 번째 "테스트"가 실제로 동일한 객체이기 때문에을 반환 합니다. 이러한 방식으로 인턴 된 문자열을 비교하는 것은 여러 비교가 아닌 단일 참조 비교가 있기 때문에 훨씬 더 빠를 수 있습니다 .String.equalschar

You can add a string to the pool by calling String.intern(), which will give you back the pooled version of the string (which could be the same string you're interning, but you'd be crazy to rely on that -- you often can't be sure exactly what code has been loaded and run up til now and interned the same string). The pooled version (the string returned from intern) will be equal to any identical literal. For example:

String s1 = "test";
String s2 = new String("test");  // "new String" guarantees a different object

System.out.println(s1 == s2);  // should print "false"

s2 = s2.intern();
System.out.println(s1 == s2);  // should print "true"

참고URL : https://stackoverflow.com/questions/3801343/what-is-string-pool-in-java

반응형