第2章 finalストーリー

2章を読んで気になったところのメモ。

final定数のコンパイルについて理解する

以下のコードをコンパイルすると

public class Hoge {
    public static final CONST = "HelloWorld!";
    public void print() {
        System.out.println(CONST);
    }
}

以下のようになります。

public class Hoge {
    public void print() {
        System.out.println("HelloWorld!");
    }
}

つまり、final定数の変更を行なう場合、もし別のクラスが参照しているようなら
別のクラスも再コンパイルしてあげないと古いデータが残ってしまいます。

論理エラーよりもコンパイルエラー!


論理エラーは、動かしてみないと気がつかず下手をすると運用が始まるまで気がつかないということ
も考えられます。
その点、コンパイルエラーはコンパイルする際に気がつくことが出来る為、非常に安心です。
つまり、何を言いたいのかというと可能な限り論理エラーがコンパイルエラーとなるようなコーディング
を行なおうということです。


以下のようなコードがあったとします。

public class Hoge {
    public void print(int number) {
        ・・・・・
        number = 3;//← 実はnumberの値を変更してしまうとまずい。。
        ・・・・・
        System.out.println(number);
    }
}

これをこうするということです。

public class Hoge {
    public void print(final int number) {  // ← final修飾子を追加
        ・・・・・
        number = 3;//← ここでコンパイルエラーとなる。
        ・・・・・
        System.out.println(number);
    }
}


変更してはいけない変数というものは意外とたくさんあるような気がします。
そのような場合は、積極的にfinalを使え〜。

条件付コンパイル


以下のようなコードをコンパイルすると・・・

public class Hoge {
    private static final boolean DO_LOGGING = false;
    public int someMethod() {
        int number = 0;
        if(DO_LOGGING) {
            System.out.println(number);
        }
        return number;
    }
}

まずこうなって・・・

public class Hoge {
    public int someMethod() {
        int number = 0;
        if(false) {
            System.out.println(number);
        }
        return number;
    }
}

こうなります。

public class Hoge {
    public int someMethod() {
        int number = 0;
        return number;
    }
}


デバッグコードを本番環境のクラスから削除する場合などに使えそうです。
ちなみ、Log4JのisDebugEnabled()メソッドは、if文による比較よりずっと時間がかかるらしいです。