2013-01-21 3 views
16

나는 두 가지 질문이 있습니다풀은 언제 바뀌나요?

public static void main(String[] args) { 
    String s1 = "bla"; 
    String s2 = "b" +"l" + "a"; 
    String s3 = "b".concat("l").concat("a"); 

    if(s1 == s2) 
     System.out.println("Equal"); 
    else 
     System.out.println("Not equal"); 
    if(s1 == s3) 
     System.out.println("Equal"); 
    else 
     System.out.println("Not equal"); 
} 
  • s1와 같은 객체에 s2 점, s1s3하지 않는 반면합니까? (키워드의 사용이 없음).

  • 나는이 선 사용자로부터 문자열을 얻고 위의 코드에 추가하는 경우 : 사용자가 xyz를 입력하면

    BufferedReader in=new BufferedReader(new InputStreamReader(System.in)); 
    String name=in.readLine(); 
    if(name.equals("test")) 
        s1 = s1 + "xyz"; 
    

    을 프로그램이 사용자가 프로그램 출력 Equal 다른 일을 입력 Not equal을 인쇄합니다 . 이것은 전체 프로그램 실행을 통해 풀이 변경된다는 것을 의미합니까? 옵티마이 저가 컴파일시에 작동 하나 runtime에서 계속 작동합니까?

답변

15

s1과 s2는 왜 동일한 객체를 가리키는 반면 s1과 s3은 같은 객체를 가리 킵니까? (새 키워드의 사용법은 없습니다).

연결이 컴파일시 발생하기 때문에 완성 된 문자열은 첫 번째 예와 같이 상수 풀에 저장됩니다. 이것은 컴파일러에게 "알려진"특별한 경우입니다. 이는 실제로 여러 줄에 걸쳐 연결된 긴 문자열이 간단한 문자열 상수와 동일한 성능 향상의 이점을 얻도록하기위한 것입니다.

두 번째 예제에서는 런타임에 계산을 수행하므로 상수 풀의 일부가 아닙니다.

그러나 JLS에서는 문자열 상수 풀에서 수행 할 수있는 작업과 수행 할 수없는 작업에 대한 세부 사항이 고의로 남겨져 있으므로 구현마다 다른 방식으로 최적화 할 수 있습니다.이 들어갈 수있는 특정 규칙이 지정되어 있지만 구현간에 일관된이 동작에 의존하지 마십시오.

9

이유는, S1 반면 및 S3 는 같은 객체에 S1과 S2 포인트하지 않는 무엇입니까? (새 키워드의 사용법은 없습니다).

자바 StringImmutable, 그래서 문자열 클래스의 방법은 새로운 String 객체를 반환합니다 때문에

(일부 예외가 있지만 거기에 - 하나 substring 방법이다). 따라서 concat 메서드는 으로 이동하고 상수 풀에 추가되지 않는 새 문자열을 만듭니다.

은 아득히 우려 s1s2의 경우와 같이, 양 문자열 컴파일 시간 에 공지되어 있으며, 따라서 이들은 동일한 문자열 상수이다.

참고 2 문자열의 연결 작업 : -

String s2 = "b" +"l" + "a"; 

이 컴파일시에 평가하고, 결과가 첫 번째 문자열과 동일한 것으로 알려져 있으며, 하나 개의 항목이 일정하게 이루어집니다 풀.

3

때로는 (컴파일러에서 런타임시 String 값이 무엇인지) 컴파일러에서 String 풀을 사용하고 다른 경우에는 그렇지 않습니다.

실제로 코드를 사용하거나 사용하지 않는 사실에 의존해서는 안됩니다.

당신이 당신의 문자열 풀에서 사용되는 경우보고 싶다면, 당신은 은 javap 목록으로 코드를 컴파일 할 수 있도록 항상 주요 실행할 수 없습니다 상대적으로 자기 설명이다.