객체는 메모리를 조작하는 코드로 묶여진 메모리 덩어리다. 메모리에서, 객체는 생존시간(lifetime) 동안 객체가 변화하는 등의 상태(인스턴스 변수들의 값)를 유지한다. 정상적으로 새롭게 생성된 객체를 얻으려면, 객체에 새롭게 할당된 메모리는 반드시 적절한 초기상태로 초기화되어야 한다.이 문서는 적절한 초기화를 위한 클래스의 설계에 중점을 두었다. 이제 우리는 객체 초기화관리에 사용되는 메커니즘을 심층적으로 실펴볼 것이다.
자바의 초기화 기법 이면의 동기(motivation)
객체생명의 시작에서 자바가상머신(이하 JVM)은 객체의 인스턴스 변수들에게 제공된 힙에 충분한 메모리를 할당한다. 메모리가 최초 할당될 때, 그것이 데이터를 포함하였는지 예측할 수 없다. 만약 메모리가 그대로 사용된다면, 객체의 행동 또한 예측할 수 없다. 따라서 객체가 다른 코드들에 의해 사용되기 전에 이러한 시나리오를 방지하기 위해 자바는 최소한의 예측가능한 초기화 값으로 메모리를 초기화 한다.
초기화되지 않은 데이터는 일반적인 버그의 원인이 때문에, 초기화는 중요하다. 예를 들어, 데이터의 적절한 초기화를 강요하는 기법이 적용되지 않은 C의 경우에는 초기화되지 않은 데이터로 인한 버그가 정기적으로 발생한다. C 프로그래머는 항상 반드시 데이터가 메모리에 할당되고, 사용되기 이전에 데이터의 초기화를 기억해야만 한다. 이와 대비되어 자바는 새롭게 객체가 생성되며 차지하는 메모리의 적절한 초기화가 보장되도록 개발자에게 도움을 주는 기법을 내장하고 있다. 이들 기법의 적절한 사용은 개발자가 설계한 객체가 부적합한 초기상태를 가지고 생성되는 것을 방지한다.
자바는 객체의 적절한 초기화를 보장하기 위한 다음과 같은 세가지 기법을 가진다 :
instance initializers (인스턴스 초기화 블록으로 부르기도 한다.)
instance variable initializers
constructors. (Instance initializers 와 instance variable initializers 를 통틀어 "initializers" 라고도 한다.)
(Note. "Intializers"는 초기화 장치 쯤으로 해석하면 되지 않을까 했지만, 정확한 우리말이 어려워 번역하지 않았음.)
이 모든 기법은 객체가 생성될 때 자동으로 수행되는 자바코드라 할 수 있다. 개발자가 new 연산자나 Class 클래스의 newInstance() 메서드를 써서 새로운 객체를 위한 메모리를 할당할 때, JVM은 개발자가 새롭게 할당된 메모리를 사용할 수 있게되는 시점 전에 초기화 코드의 수행을 보장한다. 만약 클래스들이 새롭게 생성된 객체를 위한 적절한 상태를 제공하는 initializer 나 생성자를 언제나 가지도록 설계된다면, 적절하게 초기화되지 못한 객체를 생성하거나 사용할 방법이 없을 것이다.
기본 초기값들(Default Initial Values)
만약 개발자가 인스턴스 변수들을 명확하게 초기화하지 않는다면, 해당 변수의 타입에 근거하여 변수들에 예측가능한 기본 초기값들이 부여될 것이다. 표1 은 각 변수형에 따른 기본 초기값을 보여준다. (기본 초기값들은 인스턴스 및 클래스 변수들 둘 다를 위한 것이다. 지역변수에는 기본초기값이 주어지지 않는다. 지역변수들은 사용하기 전에 반드시 명확한 초기화를 해야만 한다.)
Type
|
Default Value
|
| boolean | false |
| byte | (byte) 0 |
| short | (short) 0 |
| int | 0 |
| long | 0L |
| char | \u0000 |
| float | 0.0f |
| double | 0.0d |
| object reference | null |
만약 개발자가 인스턴스 변수를 명시적으로 초기화하지 않았다면, new 연산자가 객체의 참조를 반환할 때 변수는 기본 초기값을 가질 것이다. 예를 들어, 여기 innerCoffee 라는 명시적으로 초기화되지 않은 필드를 가진 CoffeeCup 이라는 클래스가 있다. (클래스의 생성자나 initializer 도 없다.) :
| // In source packet in file init/ex1/CoffeeCup.java // This class has no constructors or initializers class CoffeeCup { private int innerCoffee; //... } |
결과적으로 새로운 CoffeeCup 객체의 참조가 new 연산자에 의해 최초로 리턴되었을 때, innerCoffee 필드는 기본 초기값을 가지고 있을 것이다.
개발자가 명시적으로 100 이란 값으로 innerCoffee 필드를 초기화하는 것의 의미는, CoffeeCup 객체가 생성될 때 innerCoffe 에는 두 번의 효과, 두 번의 초기화가 일어날 것이란 이야기다. 첫번째로 innerCoffee 는 기본 초기값인 0 이 주어질 것이며, 다음으로 0 에 적절한 초기값인 100 으로 덮여씌여질 것이다. 이 모든 일은 JVM 이 새로운 객체를 생성하는 동안 일어난다. (새로운 객체의 참조를 리턴하기 전에...) new 연산자로부터 반환된 새로운 CoffeeCup 객체가 참조되는 시점에 innerCoffee 필드는 100 으로 셋팅될 것이다.
>> Java 에서 객체의 초기화 (2) 로 이어짐.
댓글 없음:
댓글 쓰기