Java の static 変数は奥が深い....
2008.04.04
少し不調でエントリが久々になってしまいました。
で....マクロ話の続きです。
一応 Java では、条件コンパイル(みたいなもの)がないわけではないのです。これそんなに知られていないのには、理由がありますね。というは、
private static final boolean DEBUG = false;
..............
if( DEBUG ) {
log.debug( "診断メッセージ" );
}
みたいなことをさせる...ということしか出来ないわけです。言い換えると、
- 1. static final で宣言された変数の値は、定数(みたいなもの)だ。
- 2. だから最適化の中で、常にfalseの条件で囲まれるなど、「非到達」と判定されたブロックは、コンパイル結果をあえてクラスファイルに含める必要はない!
という考え方のもとに、「条件コンパイル(みたいな)」結果が得られる、というものです。実際、出来たクラスファイルをテキストエディタで開いて、「診断メッセージ」があるかどうかを見てみれば確認できますよね。
....しかし、これ、いわゆる「条件コンパイル」とは大きく違います。たとえば、何か外部のライブラリが「あった」時に、そのライブラリを使う....というのを条件コンパイルでするケース(UNIX の C コードだと、./configure の結果からするこういうタイプの場合分けがメチャ多いですよね)では、Java では書きようがないです。それこそ設定ファイルベースでの Strategy を行う(それも共通化されたインターフェイスがあれば、の話)しかないです。
同じことをするライブラリなんだけども、いろいろな作者のものが勝手に乱立しインターフェイスに共通性がない....という場合だと、自分でそれらをラップして共通のインターフェイスに合わせるような Adaptor を作るしか手がないわけです。
要するに、
条件コンパイル機能 ⊃ Javaのstatic final 宣言による代用
なのは言うまでもないです.....ちょっと「条件コンパイル」と呼ぶにはためらわれるような実装です。で、この「代用」を行うこと自体が、実際には副作用を持ってしまった...という話があったりします。それは、
static final で宣言された変数を変更した時に、この変数を利用している他のクラスの明示的な再コンパイルが必要になる。
ということです。これは、static final 宣言=定数として、他のクラスをコンパイルする時にこれを値の参照ではなくて、その値をそのまま埋め込んでコンパイルしてしまい、なおかつこのクラスが「static final 宣言のあるクラスに依存する」という情報をクラスファイル中に保持しない...ということが原因になります。
ややこしいですね!これだったら無理してstatic final 変数を定数化しない方が良かったように思いますね....→参考
投稿者 : 杉浦 こずえ | 投稿日時 : 2008.04.04 17:31
あすなろBLOGのトラックバック・コメントは承認制になっています。
すぐにブログに反映されませんので、ご了承ください。





