2012-05-20 4 views
1
class A { 
    String s = "abc"; 
} 

class B { 
    String s = "abc"; 

    static public void main(String[]args) { 
      A a = new A(); 
      B b = new B(); 
      System.out.println("a.s==b.s : " + (a.s==b.s)); 
    } 
} 
출력

: 리터럴이 클래스 파일의 "정수 풀"부분에 기록되어있는 경우자바 : 2 개의 클래스에서 2 개의 리터럴 (동일한 내용)이 어떻게 동일한 인턴 된 문자열을 사용합니까?

a.s==b.s : true 

,이 개 클래스에 2 리터 (같은 내용을) 오는 방법은 같은 구금 문자열을 사용? 컴파일러는 어떻게 이들을 링크합니까?

+3

그들은 수업 로딩 시간에 인턴을받습니다. –

답변

1

모든 String 개체가 들어가는 문자열 풀이 있습니다. 사실 HashMap<String>입니다. String.intern() 메서드는 String을 반환합니다. 구현은

if (stringPool.contains(this)) 
    return stringPool.get(this); 
else { 
    stringPool.put(this, this); 
    return this; 
} 

클래스를로드하는 동안 String 객체가 생성되고,이 모든 클래스들 경우처럼 공유의 결과가 intern()를 호출 한 결과로 대체있어 본질적으로.

+0

고맙습니다. 그렇다면 '클래스 B'를 로딩 할 때 새로운 String 객체가 생성되지만 '클래스 A'를로드 할 때 생성 된 인턴 된 문자열로 대체되므로 즉시 사용할 수 있습니다. –

+1

글쎄, 나는 "효과적으로"그리고 "본질적으로"말하기에주의했다. 확실히 그런 식으로 일어날 필요는 없으며 영리한 실행으로 피할 수 있습니다. –

4

이것은 Java Language Specification section 3.10.5 정확히 명시된대로 :

또한, 항상 문자열 리터럴은 String 클래스의 동일한 인스턴스를 나타냅니다. 이는 문자열 리터럴 또는 더 일반적으로 상수 표현식 (15.28 절)의 값인 문자열이 String.intern 메서드를 사용하여 고유 한 인스턴스를 공유하도록 "인턴드"되기 때문입니다.

설명이 포함되는 예를 들어, 다음있다 : 다른 패키지의 다른 클래스 내에서

리터럴 문자열은 마찬가지로 동일한 문자열 객체에 대한 참조를 나타냅니다가.

String.intern()

는 다음과 같이 설명되어 있습니다 :

는 문자열 객체의 표준 표현을 반환합니다.

초기에 비어있는 문자열 풀은 String 클래스에 의해 비공개로 유지됩니다.

intern 메서드가 호출 될 때 equals (Object) 메서드에 의해 결정된대로이 String 객체와 동일한 문자열이 풀에 이미 있으면 풀에서 문자열이 반환됩니다. 그렇지 않은 경우,이 String 오브젝트가 풀에 추가되어이 String 오브젝트에의 참조가 돌려 주어집니다.

두 문자열 s 및 t에 대해 s.intern() == t.intern()은 s.equals (t)가 true 인 경우에만 true입니다.

모든 리터럴 문자열과 문자열 값의 상수 표현식은 금지됩니다. 문자열 리터럴은 The Java ™ Language Specification의 3.10.5 절에 정의되어 있습니다.

귀하의 예에서 본 행동에 대한 모든 내용입니다.

1

모든 내부 문자열을 포함하는 String.class에서 static final Set<String>을 상상해보십시오. 동일한로드 된 String 클래스를 공유하는 모든 클래스는 동일한 내부 문자열을 볼 수 있습니다.String은 루트 클래스 로더 중 하나가로드하므로 단일 JVM 인스턴스의 모든 항목에서 공유됩니다.

관련 문제