2014년 1월 14일 화요일

[10-5] final 이 붙은 지역변수?

Q. 지역클래스에서 외부클래스의 인스턴스멤버와 static멤버에 모두 접근할 수 있지만,
지역변수는 final이 붙은 상수만 접근할 수 있는 이유는 무엇인가?


A. 메서드가 수행을 마쳐서 지역변수가 소명된 시점에도, 지역클래스의 인스턴스가 소멸된 지역변수를 참조하려는 경우가 발생할수 있기 때문이다.

Q. 그렇다면 final이 붙은 지역변수는 소멸이 안되나?

A. 지역변수는 final 로 지정하면 JVM constant pool 에서 따로 변수를 관리한다.
따라서 지역클래스를 포함하고 있는 메서드와 메서드 안의 'final' 지역변수는 생명주기가 달라진다. 이 이유로 메서드가 가비지 컬렉터에 반납되어도 메서드 안의 final 지역변수는 constant pool에서 계속 보관하고 있기 때문에 이를 참조하고 있는 지역클래스의 인스턴스는 문제없이 동작할 수 있다.

Q. constant pool(상수 풀)이란? (추가내용)

방금 생각남 : String 도 변경할수 없었지? final 도 상수로 지정할때 쓰고...
                    '상수 풀'에 관리되니까 String 도...

String클래스의 intern메서드와 constant pool (상수풀)
Java에서 쓰이는 모든 String 객체는 상수풀에서 관리됩니다상수풀은 클래스와 같은Heap Permanent area(고정 영역)에 생성되어 Java 프로세스의 종료까지 그 생을 함께 합니다.
String new로 생성하지 않고 "" 리터럴을 사용하여 생성할경우내부적으로 new String() 메소드 호출 이후에 String.intern()이라는 메소드가 호출되어 고유의 인스턴스를 공유하도록 interned됩니다.  이것은 생성한 String Constant pool에 등록하는(만약 이전에 같은 char sequence의 문자열이 이미 상수풀에 있다면 문자열을 힙에서 해제하고 그 상수풀의 레퍼런스를 반환작업을 수행하지요.
같은 패키지의 같은 클래스 내에서는 정수(literal)스트링들은 동일한 String 객체를 참조한다.
)
String a = "JAVA";
String b = "JAVA";
의 경우 a == b  true
String a = new String( "JAVA" );
String b = "JAVA"
의 경우 a == b  false
String a = new String( "JAVA" );
a = a.intern();
String b = "JAVA";
의 경우 a == b  true
일반적으로 문자열들을 비교하기 위해서 equals메서드를 사용하지만, equals메서드로 문자열의 내용을 비교하는 것보다는 등가비교연산자(==)를 이용해서 주소(4 byte)를 비교하는 것이 더 빠르다.
명시적인 new String() 생성자를 호출했기 때문에 각각의 문자열이 상수풀에 intern되는 과정 없이 제각각의 heap 주소에 생성된 것입니다.
수형(int)값을 String으로 변환하는 두 가지 방법
1) String클래스의 valueOf메서드
2) 덧셈연산자(+)를 사용

댓글 없음:

댓글 쓰기