들어가며
static 선언은 클래스 변수와
클래스 메소드의 선언 이외에
다른 용도로도 사용이 된다.
사용 빈도가 높지는 않으나
상황에 따라 유용하게 사용될
수 있으니
알아두는 것이 좋다.
static 초기화 블록(Static Initialization Block)
다음 클래스 정의를 보자.
이 클래스에는 프로그램의
실행 날짜를 저장할 목적으로
변수가 하나 선언되어 있다.
그리고 이 변수는 변경의 대상이
이니고, 참조만을 목적으로 하므로,
'클래스 변수'로 선언을 하였다.
class DateOfExecution{
static String date; // 프로그램의 실행 날짜를 저장하기 위한 변수
public static void main(String[] args){
System.out.println(date);
}
}
위에서 클래스 변수 date를
선언과 동시에
오늘 날짜 정보를 담고 있는
문자열로 초기화 하려 한다.
그런데 오늘 날짜를 얻어오는
코드는 다음과 같다.
LocalDate nDate = LocalDate.now();
date = nDate.toString();
변수 date가 인스턴스 변수라면
위의 두 문장을 생성자에 넣으면
된다.
그러나 이는 클래스 변수이므로
생성자는 적절하지 않다.
이러한 상황을 고려하여 자바는
'static 초기화 블록'이라는 것을
제공한다.
그리고 위의 두 문장을 static으로
초기화 블록으로 감싼 결과는
다음과 같다.
static{
LocalDate nDate = LocalDate.now();
date = nDate.toString();
}
'static 초기화 블록'은 클래스
변수와 마찬가지로,
가상 머신이 클래스의 정보를
읽어 들일 때,
즉, 가상 머신이 클래스를 로딩
할 때 실행된다.
따라서 다음과 같이 static 초기화
블록을 사용하면
클래스 변수를 선언과 동시에
초기화할 수 있다.
import java.time.LocalDate;
class DateOfExecution{
static String date;
static{ // 클래스 로딩 시 단 한 번 실행이 되는 영역
LocalDate nDate = LocalDate.now();
date = nDate.toString();
}
public static void main(String[] args){
System.out.println(date);
}
}
/*
실행 결과
2020-08-18
*/
static import 선언
앞서 클래스 변수를 선언하면서
다음과 같이 원주율을 클래스
변수로 선언한 바 있다.
static final double PI = 3.1415;
그런데 이 값은 java.lang.Math에
실제로 클래스 변수로 선언되어
있다.
따라서 다음과 같이 이 값을
출력할 수 있다.
System.out.println(Math.PI);
앞서 언급하였듯이 다음 문장이
자동으로 삽입이 되니,
패키지 이름 java.lang을 생략하고
Math.lang을 생략하고 Math.PI로
접근이 가능하다.
import java.lang.*; // 컴파일러가 삽입하는 import 선언
그런데 다음과 같이 그냥 클래스
변수의 이름만으로 Math.PI에
접근할 수 있는 방법이 있다.
System.out.println(PI); // Math가 생략된 형태로 Math.PI 접근
다음 import 선언을 추가하는
것이 그 방법이다.
import static java.lang.Math.PI; // PI에 대한 static import 선언
이렇듯 클래스 변수와 클래스
메소드에 대한 import 선언을
할 수 있다.
더불어 Math 클래스에 정의된
클래스 메소드 전부를 대상으로
다음과 같이 import 선언을 할
수도 있다.
import static java.lang.Math.*; // 모든 클래스 변수와 메소드에 대한 import 선언
그와 관련하여 다음 예제를 보자.
import static java.lang.Math.*;
class StaticImport{
public static void main(String[] args){
System.out.println(E);
System.out.println(PI);
System.out.println(abs(-55)); // 절댓값 반환
System.out.println(max(77, 88)); // 큰 값 반환
System.out.println(min(33, 55)); // 작은 값 반환
}
}
/*
실행 결과
2.718281828459045
3.141592653589793
55
88
33
*/
적절히 그리고 최소한으로
사용한다면,
static import 선언 역시 도움이
될 수 있다.
그러나 빈번하게 사용할 경우
해당 메소드 또는 변수가
어디에 저장되고 선언된 것인지
구분이 힘들어져서
오히려 방해가 될 수도 있다.
참고 및 출처
|