23

次のようなクラスがあるとしましょう。

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 つだけを変更し、コンパイルされたクラスだけをデプロイしたいと考えています。しかし、これらのフィールドが消費者クラスでインライン化されている場合、これは不可能になりますよね?

コンパイル時定数のインライン化を無効にするオプションはありますか?

4

6 に答える 6

28

String.intern()を使用して目的の効果を得ることができますが、これについて知っている人はあまりいないため、コードにコメントを付ける必要があります。すなわち

public static final String configOption1 = "some option".intern();

これにより、コンパイル時間がインラインで防止されます。コンパイラがpermに配置するのとまったく同じ文字列を参照しているため、余分なものを作成することはありません。

別の方法として、いつでも行うことができます

public static final String configOption1 = "some option".toString();

ただし、これはコンパイルされたインターン文字列を使用せず、古い世代に新しい文字列を作成します。大したことではなく、読みやすいかもしれません。いずれにせよ、これは少し奇妙なので、コードをコメントして、それを維持している人に自分が何をしているのかを知らせる必要があります。

編集: これに関する詳細については、JLSへの参照を提供する別のSOリンクを見つけました。 文字列リテラルでintern()を使用する場合

于 2010-02-25T22:14:05.623 に答える
10

いいえ、JLS の一部です。これについては、Java Puzzlers で簡単に触れていますが、手元にコピーがありません。

これらの定数をプロパティ ファイルで定義し、それらを定期的にロードするクラスを用意することを検討するかもしれません。

参照: http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#5313

于 2008-12-18T13:23:03.623 に答える
7

実際、キーワードを削除するとfinal、定数はコンパイル時の定数ではなくなり、構成は思いどおりに機能します。

ただし、これが実際に何らかの構成を行おうとしている場合は、クラス ファイルの定数よりも管理しやすい方法に移行することを強くお勧めします。

于 2008-12-18T13:23:16.757 に答える
7

いいえ。ただし、次のような静的メソッド呼び出しに置き換えることができます。

class ApplicationDefs {

    public static String configOption1() { return "some option"; }

}

確かに、それは美しくはありませんが、あなたの要件を満たすでしょう. :)

于 2008-12-18T13:24:34.150 に答える
6

定数の非コンパイル時定数を作成することで、インライン化を禁止できます...

たとえば、nullはコンパイル時の定数ではありません。非コンパイル時定数を含む式はコンパイル時定数ではありませんが、javac はコンパイル単位内で定数の折りたたみを行う場合があります。

public static final String configOption1 = null!=null?"": "some option";
于 2008-12-18T14:14:35.890 に答える
-4

これらの値をインライン化する必要があると言うものは何もありません。public一部の,staticメンバーを宣言しているだけです。これらの他のクラスは、これらのメンバーの値を使用しています。インライン化は要求されません。finalキーワードでも

ただし、パフォーマンス上の理由から、一部の JVM はこれらの値を他のクラスにインライン展開する場合があります。これは最適化です。最適化によってプログラムの動作が変わることはありません。したがって、これらのメンバーの定義を変更すると、JVM は以前の値のインライン展開を解除する必要があります。

これが、インライン化をオフにする方法がない理由です。JVM がインライン化されていなくても問題がないか、インライン化されている場合は JVM が非インライン化を保証します。

このクラスを静的にインポートするとどうなるかわかりません。インライン化が行われていると思いますが(よ​​くわかりません)、あなたが言及した問題を引き起こす可能性があります。その場合は、基本的に静的インポートを削除しても問題ありません。

于 2008-12-18T13:38:46.493 に答える