2012-11-17 5 views
4

내 자바 클래스최종 문자열

private static final String constantString = "Constant";  
private static final Integer constantInteger = 5; 
public static void main(String[] args) { 
    String s2 = constantString + "append"; // LINENUMBER 9 
    Integer i2 = constantInteger + 7; // LINENUMBER 10 
} 

바이트 코드

LINENUMBER 9 L0 
    LDC "Constantappend" 
    ASTORE 1 
    L1 
    LINENUMBER 10 L1 
    GETSTATIC TestClass.constantInteger : Ljava/lang/Integer; 
    INVOKEVIRTUAL java/lang/Integer.intValue()I 
    BIPUSH 7 
    IADD 

질문 주전 골키퍼 : 왜 컴파일러 5 최종 정수 (constantInteger) 값을 대체하지만, 문자열은하지 않았다!

정수 변수 최종 키워드를 제거하면

자바 코드 :

private static Integer constantInteger = 5; 

바이트 코드 :

LINENUMBER 10 L1 
GETSTATIC TestClass.constantInteger : Ljava/lang/Integer; 
INVOKEVIRTUAL java/lang/Integer.intValue()I 
BIPUSH 7 

바이트 코드는 두 가지의 경우와 동일하다 (정적 최종 정수 , 정적 정수)

질문 2 : 그렇다면 Integer를 final로 사용하는 것은 무엇입니까?

+2

"그렇다면 Integer final을 만드는 용도는 무엇입니까?" 컴파일러는 값을 변경할 수 없습니다. – leonbloy

답변

5

컴파일러는 null이 아닌 값을 가진 최종 Integer가 반드시 null이 아니라는 것을 알아 차리지 않습니다. 그래서 그것은 앞으로 나아가고 그것을 unboxes. JIT 컴파일러가 코드를 작성하는 과정에서이를 개선 할 가능성이 있습니다. 이것이 응용 프로그램의 성능에 실제 문제가되는 것은 거의 없습니다.

'최종'은 성능이 아닌 의미론입니다. 언어는 의미를 보장합니다. 성능은 전적으로 구현 자들의 변덕에 달려있다. 따라서 '질문 # 2'에 명시 적으로 대답하기 위해 : 마지막 단계는 수정을 방지하는 의미를 갖는 것입니다. 또한 최종 로컬 변수 만 사용할 수있는 임베디드 익명 클래스에 대한 규칙을 유의하십시오.

3

짧은 대답 : 상수 식으로 만 교체 할 수 있습니다 static final int constantInteger = 5

컴파일러를 사용해보십시오. Java에는 소위 원시 값 (소문자 (long, int, char, ...)으로 시작하는 유형)이 있습니다. 이 값은 객체가 아니므로 상태를 가질 수 없으며 직접 바꿀 수 있습니다.

문자열 개체도 컴파일러에서 상수처럼 취급 할 수 있습니다. 런타임시 String은 문자 배열을 포함하는 컨테이너 일 뿐이지 만 컴파일 타임에 컴파일러는 String이 문자 데이터 인 것처럼 가장합니다. 그러나이 예외가 적용된 유일한 클래스는 String입니다.

비슷한 이유 때문에 StringClass을 사용할 수 있지만 주석의 값에 다른 객체 유형은 사용할 수 없습니다.

6

추측 : 이유는 문자열 인턴입니다. 컴파일러는 문자열을 인턴하고 내부 문자열의 연결을 최적화합니다. 그러나 Numbers는 인턴이 아니며 최적화가 부족한 것 같습니다.

저는 컴파일러에서 구현되지 않은 것 이외에 Integer 케이스를 최적화 할 수없는 이유를 생각할 수 없습니다. 다른 대답에서 언급했듯이 Integer +는 boxing/unboxing 작업을 포함하며 string + 및 해당 암시 적 StringBuilder 최적화 및 interning 논리와 매우 다릅니다.그래서 String + optimization은 아마도 컴파일러 구현 시점에서 "무료"로 제공 될 것입니다. Java Language Specification, v3 가입일

1

: 상수 식 (§15.28)에 의해 계산

문자열 컴파일시에 계산하고 리터럴 것처럼 후 처리된다.

두 개의 리터럴로 구성된 문자열 표현식이 컴파일 타임에 단일 리터럴로 계산됩니다. 정수는 그런 대우를 얻지 못합니다.