Ball.java

public class Ball {
    public static final String UNDER_HAT = "NONE";
}

HatOne.java

public class HatOne {
    public boolean hasBall() {
        return "ONE".equals(Ball.UNDER_HAT);
    }
}

HatTwo.java

public class HatTwo {
    public boolean hasBall() {
        return "TWO".equals(Ball.UNDER_HAT);
    }
}

MagicTrick.java

public class MagicTrick {
    public static void main(String... args) {
        HatOne hatOne = new HatOne();
        HatTwo hatTwo = new HatTwo();
        if (hatOne.hasBall() && hatTwo.hasBall())
            System.out.println("TADA!! The ball is under both hats!");
        else if (hatOne.hasBall())
            System.out.println("The ball is under hat one.");
        else if (hatTwo.hasBall())
            System.out.println("The ball is under hat two.");
        else
            System.out.println("Better luck next time.");
    }
}

자. 이 상황에서 main 메소드를 실행하면 당연히 Better luck next time. 이 녀석이 출력되겠죠. 문제는 Ball.java 클래스를 마음대로 수정해서 화면에 TADA!! The ball is under both hats! 이 메시지를 출력하는 겁니다.

전 못 풀었어요. 헐 좀 더 끈기 있게 매달려볼 걸.. 하고 후회했답니다.

답은 아래 링크에 원문과 함께 네 가지가 나와있습니다.

참조 : http://blogs.atlassian.com/developer/2008/07/magic_trick_in_java.html

updated 20080805

제 블로그 방명록에 fomuon님께서 답변 하나를 주셔서 추가합니다.

public class Ball {
    public static String UNDER_HAT = "ONE";
    static {
        new Ball();
        System.gc();
        System.runFinalization();
    }
    protected void finalize() throws Throwable {
        UNDER_HAT = "TWO";
    }
}

발상이 참 멋진거 같습니다.