четверг, 4 октября 2007 г.

Java Puzzle 52: Sum Fun

class Cache {
    static {
        initIfNeeded();
    }
    private static int sum;
    public static int getSum() {
        initIfNeeded();
        return sum;
    }
    private static boolean inited = false;
    private static void initIfNeeded() {
        if (!inited) {
            for (int i = 0; i <100; i++) {
                sum += i;
            }
            inited = true;
        }
    }
}
class Main {
    public static void main(String[] args) {
        System.out.println(Cache.getSum());
    }
}
Программа напечатает не 4950, а 9900. Это не то, что автор такого класса хотел. Весь прикол в том, что JVM инициализирует статические переменные в классе последовательно. Сначала вызывается статический блок, в котором устанавливается значение sum и inited. Затем пропускается инициализация sum. После чего inited принудительно инициализируется в false. Таким образом, при вызове getSum будет повторно увеличено значение sum. Для того, чтобы этого не произошло, надо объявить sum так:
    private static int sum = 0;
или же объявить inited так:
    private static boolean inited;
А вообще так делать не рекомендуется. Лучше сделать так:
class Cache {
    private static final int SUM = calculate();
    public static int getSum() {
        return SUM;
    }
    private static int calculate() {
        int sum = 0;
        for (int i = 0; i <100; i++) {
            sum += i;
        }
        return sum;
    }
}

Комментариев нет:

Отправить комментарий