Whiteship's Note

null은 캐스팅이 되는건야 안 되는거야?

Java : 2010.03.02 13:38


    @Test
    public void nullCasting() throws Exception {
        Class nullClass = (Class)null;
        Class thisClass = this.getClass();
        assertThat(nullClass, is(nullValue()));
        assertThat(thisClass, is(instanceOf(Class.class)));
        assertThat(nullClass, is(not(instanceOf(Class.class))));
    }

캐스팅이 된것 같다. 하지만 안 됐다. 

저 상태에서 컴파일 에러가 날 것 같지만 컴파일 에러가 발생하지 않았다.

Whiteship whiteship = (Whiteship)thisClass;

하지만 이런 코드를 적어보면 컴파일 에러가 난다. 

그렇다면 null을 어느 타입으로든 캐스팅 하는건 문법적인 에러가 아닌가본데... 사실 그 안의 인스턴스를 사용하려들면 에러가 난다.

nullClass.getDeclaredMethods();

즉 이런 코드를 실행하면 NullPointerException이 발생하게 된다.

 따라서 null을 다른 타입으로 캐스팅을 하는 코드를 작성 하더라도 컴파일 에러가 나지는 않지만 그렇다고 해서 실제로 캐스팅이 된 것은 아니다.

대체 이런 짓을 왜 할까? 언제 null을 다른 타입으로 캐스팅 하는 코드를 써먹을 수 있을까?
퀴즈로 남겨줄까 한다. 후훗.

힌트이자 정답을 알려주자면...스프링의 ClassPathResource의 소스코드를 보면 나와있다.
top

  1. Favicon of https://helols.tistory.com BlogIcon is윤군 2010.03.02 14:55 신고 PERM. MOD/DEL REPLY

    바지런한데요 ;;ㅋㅋ

    Favicon of https://whiteship.tistory.com BlogIcon 기선 2010.03.02 15:23 신고 PERM MOD/DEL

    내가 선수친건가? ㅋㅋ

  2. Favicon of http://blog.lckymn.com BlogIcon Kevin 2010.03.02 19:34 PERM. MOD/DEL REPLY

    ClassPathResource 코드는 본적이 없지만,
    제가 알고 있는 차이점중 지금 생각나는걸로는
    이런게 있습니다.

    varargs 사용할때

    public void test(String ... args)
    {
    }

    test() 메소드에 test(null) 을 보내면
    args == null

    test((String) null) 을 보내면
    args != null
    args.length == 1
    args[0] == null

    컴퓨터 언어인 ALGOL을 디자인했으며, Null References 를 고안해낸 장본인인
    영국의 유명한 컴퓨터 과학자인 Tony Hoare 가 얼마전에
    Null References 는 10억 달러짜리 실수 (The Billion Dollar Mistake) 라고
    고백(?) 한적이 있죠.
    근데, Tony Hoare 말처럼 그당시 컴퓨터 성능을 고려했을때
    어쩔수 없는 선택이었겠죠.

    Favicon of http://whiteship.me BlogIcon 기선 2010.03.02 20:34 PERM MOD/DEL

    헐.. 신기하네요. 되도록이면 null을 캐스팅하는 코드는 안쓰는게 좋겠다는 생각인데, 스프링 코드에 보니까 나름 재치있게 사용한 것 같아 보이는 코드가 있어서 눈여겨 봤었습니다.

    생성자 호출이었는데..

    Whiteship(name) 이라는 생성자 내부에서 Whiteship(name, Class), Whiteship(name, SpringSprout) 중에 뒤에있는 녀석을 호출하고 싶을 때.

    this(name, (SpringSprout)null)

    이런식으로 사용해서 호출되는 생성자를 선택하더라구요.ㅎㅎ

  3. Favicon of http://toby.epril.com BlogIcon 토비 2010.03.02 22:06 PERM. MOD/DEL REPLY

    null은 클래스나 인터페이스와 같은 레퍼런스 타입으로 컨버팅이 가능하도록 만들어진 null 타입의 레퍼런스이기 때문에 가능한 일이지. 그러니까 어떤 타입 변수에도 null을 넣을 수 있고, 직접 비교도 가능한거지.

    Favicon of http://whiteship.me BlogIcon 기선 2010.03.02 22:58 PERM MOD/DEL

    흠냐.. 마치 수학의 공집합이 떠오르네요.
    공집합은 모든 집합의 부분집합이라나 머라나.

  4. Favicon of https://helols.tistory.com BlogIcon is윤군 2010.03.03 01:30 신고 PERM. MOD/DEL REPLY

    여긴 언제나 어려운 이야기들로 ... ㅋ 넘쳐나는군요! ㅋ

    Favicon of http://whiteship.me BlogIcon 기선 2010.03.03 05:19 PERM MOD/DEL

    음냐;; 그러게. 나도 잘 모르는 이야기들이얌;; @_@

  5. Favicon of http://lf.hisfy.com/ BlogIcon 엽우 2010.03.11 22:48 PERM. MOD/DEL REPLY

    전 null이 OOP의 상속 개념을 뒤흔든다고 생각합니다.

    Sup sup;
    Sub sub; // Sub extends Sup

    이런 코드가 있을때 (Sup) sub는 되지만 (Sub) sup은 다운캐스팅을 하면서 예외가 발생하죠.
    그럼 (SomeClass) null이 런타임 자체까지 오류가 없다는 말은
    null 인스턴스(라고 보기 힘들지만)가 SomeClass와 동등하거나 하위 클래스의 인스턴스로 간주되는 거죠.

    다시 말하며 null은 임의의 클래스의 하위 인스턴스다,
    즉 모든 클래스의 하위 클래스를 가진다, 인데 이게 다중 상속도 아니면서 애매하게 꼬이는 거죠.

    Favicon of https://whiteship.tistory.com BlogIcon 기선 2010.03.12 09:52 신고 PERM MOD/DEL

    네 그러게요.

    "null은 임의의 클래스의 하위 인스턴스다"
    이게 딱 공집합의 특징이죠.
    "공집합은 모든 집합의 부분집합이다."

    하지만 뭐 null을 캐스팅 할 일은 드물것 같아서.. 별로 신경 안쓰이는데 그보다는 NullPointerException이 정말 귀찮아 죽겠네요;;

Write a comment.




: 1 : ··· : 5 : 6 : 7 : 8 : 9 : 10 : 11 : 12 : 13 : ··· : 140 :