すべてのコンパイル時間定数がインライン化されていますか?
-
22-08-2019 - |
質問
私がこのようなクラスを持っているとしましょう:
class ApplicationDefs{
public static final String configOption1 = "some option";
public static final String configOption2 = "some other option";
public static final String configOption3 = "yet another option";
}
私のアプリケーションの他のクラスの多くは、これらのオプションを使用しています。次に、オプションの1つだけを変更して、コンパイルされたクラスのみを展開したいと思います。しかし、これらのフィールドが消費者クラスに並んでいる場合、これは不可能になりますか?
コンパイル時間定数のインニングを無効にするオプションはありますか?
解決
string.intern()を使用して目的の効果を得ることができますが、これについて多くの人が知っているわけではないため、コードをコメントする必要があります。すなわち
public static final String configOption1 = "some option".intern();
これにより、コンパイル時間のインラインが妨げられます。コンパイラがPermに配置するのとまったく同じ文字列を参照しているため、余分なものを作成していません。
代替手段として、いつでもできます
public static final String configOption1 = "some option".toString();
ただし、これはコンパイルされたインターン文字列を使用しないため、古い世代に新しい文字列が作成されます。大したことではなく、読みやすいかもしれません。いずれにせよ、これは少し奇妙なので、あなたがしていることを維持している人々に通知するためにコードにコメントする必要があります。
編集:これの詳細については、JLSへの参照を提供する別のSOリンクを見つけました。文字列リテラルでインターン()を使用するタイミング
他のヒント
いいえ、それはJLSの一部です、私は恐れています。これは、Java Puzzlersで簡単に触れられていますが、手に入れるコピーはありません。
これらの定数をプロパティファイルで定義することを検討し、定期的にロードするクラスを持っていることを検討するかもしれません。
参照: http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#5313
いいえ。ただし、以下のように、静的メソッド呼び出しに置き換えることができます。
class ApplicationDefs {
public static String configOption1() { return "some option"; }
}
確かに、それは美しくありませんが、それはあなたの要件を満たすでしょう。 :)
実際、あなたがいれば を削除します final
キーワード 定数はコンパイル時間定数であることを停止し、次に構成 動作します あなたが望むように。
ただし、これが実際にあなたがやろうとしているある種の構成である場合、一部のクラスファイルの定数よりも管理しやすい方法に移動する必要があることを強くお勧めします。
一定の非コンパイル時間定数を作成することで、インラインを阻害できます...
例えば、 null
コンパイル時定数ではありません。 Javacがコンパイルユニット内で一定の折りたたみを行う可能性がありますが、コンパイル非コンパイル時定数を含む式はコンパイル時定数ではありません。
public static final String configOption1 = null!=null?"": "some option";
ここには、これらの値をインラインする必要があると言うものは何もありません。あなたはただいくつか宣言しています public
, static
メンバー。これらのクラスは、これらのメンバーの値を使用しています。インラインは尋ねられません。さえ final
キーワード
しかし、 パフォーマンスの理由, 、いくつかのJVMはそうかもしれません 列をなして これらの他のクラスのこれらの値。これは最適化です。プログラムの動作を最適化する必要はありません。したがって、これらのメンバーの定義を変更する場合、JVMは un-inline 以前の値。
これが、インラインをオフにする方法がない理由です。 JVMがインラインではなく、問題はありません。また、JVMがinliningを保証します。
このクラスを静的にインポートするとどうなるかわかりません。インライン化が実行され、あなたが言及したトラブルを引き起こす可能性があると思います(確かではありません)。その場合は、基本的に静的インポートを削除できれば大丈夫です。