定数として使用していた。finalを定義しているクラスをコンパイルし、それを参照している、例えばmainクラスなどを起動しても、変更が反映されない。変更前の値を使用してしまう。いう現象に悩まされていました。試しに次のような定数クラスを用意し、適当にそれらのフィールドを出力するmainクラスを作成してみる。mainクラスは別々のJavaソース、クラスファイルになっている点。staticなフィールドについては、どうもインライン展開され、呼び出し側のクラスに直値が書き込まれてしまうらしい、と言うことである。そのことが明記されている文章は、JavaHouseに一件見つかった。残りは、finalメソッドについてのインライン化について取り上げられており、finalフィールドについては少々うやむやである。final値を変更した場合、参照側のクラスも再コンパイルが必要であることには変わりはなかった。WebLogicで、プロジェクト共通の定数クラスの値だけ変えても、Servlet側で反映してくれなかったのはこれが原因だったのか・・・。このインライン化は、finalされたクラスを直接.classで参照していようと、jarファイルの中であろうと関係なく行われるようである。mainクラスとして逆アセンブルした結果を、.class直接参照してコンパイルしたmainクラスの逆アセンブル結果とdiffしてみたところ、相違点は無かった。jarファイルの中から参照しているクラスを探し、適切にfinalフィールドをインライン展開できていた。finalの組み合わせ自体は昔から使われてきた手法である。関わらず、今までこの問題が表面化してこなかったのは何故か、非常に疑問に思う。先に示したJavaHouseの記事については1999年のものである。javacがある程度参照の連携を自動認識し、参照・被参照クラスをコンパイルしてくれるのではあるまいか?・・・そういわれれば、今回この現象が発覚したのは、被参照クラスと参照クラスを、別ディレクトリで管理していたからかも知れない。被参照クラスはAppサーバ側の設定で直接classpathを切ってしまっており、参照クラスはServletである。コンパイル時のディレクトリ構造も別になっており、ServletクラスはCLASSPATHで被参照クラスを探索するようになっていた。finalにしてしまうとその後値を迂闊に変更できなくなる、という事にも結びつく。Log4jのLogManager#DEFAULT_CONFIGURATION_KEYなどがdeprecatedになっていてもなお、消えることが無いのも、finalであるが故に、利用アプリのクラスでインライン展開されてしまっている可能性があるからであろう。log4jのjarを入れ替えればそれで済む話ではなくなってしまっているのだ。java_static_final_test.ziphoge.bakみたいなディレクトリは、元はhogeディレクトリ。hoge.jarはhogeディレクトリをjarでまとめたもの。念のためhogeディレクトリはhoge.bakにリネームしただけ。10:21:24md5:76603be6ef9569ca2b014ad97f08b227sha1:5014a191876e356d89efa22d0a7161890a0809c2コメントコメントを投稿するにはログインして下さい。Kamiyamane。