케네스로그

[Java] 변수의 선언 및 초기화 방법 본문

Dev/Java

[Java] 변수의 선언 및 초기화 방법

kenasdev 2022. 1. 30. 09:51
반응형

변수 선언 및 초기화하는 방법

변수의 선언

메모리 공간에 변수 타입에 맞는 크기의 저장 공간이 확보되며, 할당된 메모리 공간은 변수 이름을 통해 접근할 수 있게 됩니다.

 

변수의 초기화

변수 선언으로 할당된 공간에 처음으로 값을 저장하는 행위를 말합니다. 변수 선언 시 메모리에 변수를 위한 공간이 할당되지만, 어떤 값이 저장되는지는 알 수 없습니다. C와 같은 언어에서는 쓰레기값이 저장되어 초기화를 하지 않으면 문제가 발생할 수 있습니다. 

int age = 20;

변수의 초기화는 다음과 같은 형식으로 이루어집니다. 대입연산자를 기준으로, 좌측에는 변수이름과 우측에는 변수에 저장될 값이 위치합니다.

 

a. 묵시적 초기화 implicit initalization

Java에서는 데이터 타입별로 초기화값이 정해져있기에, 초기화를 하지 않는다면 데이터 타입에 따라 초기화값이 저장됩니다. 타입별 초기화 값은 이전 포스트에서 확인 가능합니다.

 

b. 명시적 초기화 explicit initialization

변수 선언과 동시에 초기화 하는 방법을 말합니다. 위의 예시와 같습니다.

 

c. 초기화 블럭 initialization block

class ExplicitInitialization {
	static {
		// 클래스 초기화 블럭
	}
	
	{
		// 인스턴스 초기화 블럭
	}
}
  • 클래스 초기화 블럭: 클래스변수의 복잡한 초기화에 사용됩니다. 블럭 내에서는 로직도 추가할 수 있기에 명시적 초기화만으로 부족할 때 사용됩니다.
  • 인스턴스 초기화 블럭: 인스턴스 변수의 복잡한 초기화에 사용됩니다. 모든 생성자가 공통으로 수행해야 하는 로직이 있을 때 사용됩니다.

 

d. 생성자 constructor

인스턴스 생성 시 생성자 함수에 의해 명시적으로 초기화합니다. 이 생성자에 관해서는 차후의 포스트에서 다루도록 하겠습니다.

 

 

변수 선언/초기화와 멀티쓰레드 문제

int a = 10;
System.out.println(a);

위의 예시에서 a를 선언하고 할당했습니다. 우리는 한줄의 코드로 작성했지만, 바이트코드 상으로는 2줄로 표현됩니다.

 

  1. 변수 a를 정의한다.
  2. 리터럴 값 10을 변수 a에 할당한다.

 

단일 쓰레드 환경에서는 크게 문제가 발생하지 않을 평범한(?) 코드입니다. 하지만, 여러 쓰레드에서 해당 코드를 실행한다면 문제가 발생할 수 있습니다. 아래의 예는 그에 대한 예시입니다.

 

두개의 쓰레드가 알파, 베타가 각각 위의 코드를 실행합니다. 문제는 a라는 똑같은 변수를 동시에 접근하여 연산을 수행하다보니 중간에 값이 변경됩니다. 따라서 알파 쓰레드의 출력문에서는 a가 기대값 20이 아닌 10을 출력합니다. 아무런 에러도 발생하지 않고 정상적으로 동작한 프로그램이지만, 결과물은 치명적으로 달라질 수 있습니다. 싱글톤 패턴에서 double checked locking하는 이유가 여기에 있습니다.

반응형