[Java] 파생 클래스가 아니라.. 딱 내 클래스인가?

뭐.. 제목이 저래.. 라고 생각하시는 분도 분명 계실테고.. 저 역시 뭐 제목이 이래.. 라고 생각하고 있습니다.. 먼저 아래와 같은 클래스 계층이 있다고 칩시다..

사용자 삽입 이미지
Geometry를 부모로 하는 세개의 자식 클래스입니다.. 예를 들어 아래처럼 코딩을 했습니다..

Geometry g = new Rectangle();

이제 이제 g 객체가 Circle이냐.. Rectangle이냐.. 아니면 Triangle이냐.. 아니면.. Geometry이냐를 어떻게 알 수 있을까요? 뭐 이런거야.. 자바에는 편리한 instanceof가 있으니 아래처럼 하면되지라며.. 코딩합니다..

Geometry g = new Rectangle();

if(g instanceof Rectangle) {
    System.out.println("Type is Rectangle");
}

if(g instanceof Circle) {
    System.out.println("Type is Circle");
}

if(g instanceof Triangle) {
    System.out.println("Type is Triangle");
}

if(g instanceof Geometry) {
    System.out.println("Type is Geometry");
}

자바를 잘아신다면.. 어.. 이거 아닌데.. 라고 바로 하실테지만.. 저는 단지.. 그냥 냄새가 좀 나는데.. 는 정도였답니다.. 여튼, 실행해보면 2개의 조건문에서 true를 만나게 됩니다.. 3번 코드의 if 문과 15번 코드의 if 문.. 즉 g는 Rectangle이면서 동시에 Geometry 타입입니다.. 당연한 결과이지요.. 하지만 원하는 것은 딱… “나는 나다!”라는 것이죠.. 즉, 위의 경우에는 g는 Geometry가 아니라 Rectangle다! 라는 것을 판별해야 한다는 것입니다..

자바는 C/C++ 언어가 가지지 못한 강력한 기능이 있습니다.. 실행시간에서의 타입 정보(RTTI)인데요.. 이 RTTI를 위해 자바는 모든 객체에 대해서 자신의 타입에 대한 정보를 담고 있습니다.. 이를 이용해 우리가 원하는 바를 얻을 수 있는 코드는 아래와 같습니다..

Geometry g = new Rectangle();

if(g.getClass() == Rectangle.class) {
    System.out.println("Type is Rectangle");
}

if(g.getClass() == Circle.class) {
    System.out.println("Type is Circle");
}

if(g.getClass() == Triangle.class) {
    System.out.println("Type is Triangle");
}

if(g.getClass() == Geometry.class) {
    System.out.println("Type is Geometry");
}

이제 정확히.. 오직 3번 코드에 대한 if문에서만 true인, “나는 나다!”라는 결과를 얻을 수 있게 됩니다..

[Java] 정적 초기화 블럭(static initialization block)

클래스에서 정적 변수나 매서드는 클래스 타입에 대한 인스턴스화 없이도 호출하거나 참조할 수 있는 요긴한 녀석들인데요.. 이 정적 변수를 사용하기 전에 미리 초기화해 놓을 필요가 있는 경우가… 대부분입니다. 뭐.. 간단히 클래스 안에서 정적 변수를 선언할때 값을 지정해 버리면 될 일이지만… 즉, 아래처럼요..

class IAMABOY {
    static int a = 100;
}

뭐.. 간단하죠? 하지만 여기에 더해서 추가적으로 자바에서는 정적 초기화 블럭이라는 방법을 제공합니다.. 가끔 사용하는 방법인지라.. 잊고.. 필요해서 사용할라치면 기억에서 가물가물.. 가물치가 되는지라.. 정리를 한번 해보렵니다.. 뭐.. 예시 코드 한방 날리면..

class IAMABOY {
    static int a = 100;

    static {
        for(int i=0; i<100; i++) {
            a = i;
        }
    }
}

즉.. 정적 초기화 블럭은 클래스의 인스턴스화에 상관없이 딱 한번 호출되는 절차적인 코드들로 이루어진 블럭입니다.. 요놈.. 요놈.. 가만히 보니.. 단위 테스트 기능 구현에 적용하면 딱... 이겠구나.. 싶어집니다..