본문 바로가기

Java/Chapter 10. 클래스 변수와 클래스 메소드

[Java] 10.04 - 또 다른 용도의 static 선언

들어가며

 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 선언 역시 도움이
될 수 있다.

 그러나 빈번하게 사용할 경우
해당 메소드 또는 변수가

 어디에 저장되고 선언된 것인지
구분이 힘들어져서

 오히려 방해가 될 수도 있다.


참고 및 출처

윤성우의 열혈 Java 프로그래밍
국내도서
저자 : 윤성우
출판 : 오렌지미디어 2017.07.05
상세보기