[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[jfriends-ml 10235] 定数パターンの インライン化問題
高橋(徹)です。
第3回読書会のタイプセーフenumの是非に関していろいろ意見が出てい
ます。タイプセーフな定数と、プリミティブ型/String型の定数とにつ
いて、コンパイルされた際のインライン問題についてはまだ出ていなか
ったようなので、以下にまとめます。
なお、検証に使った環境は以下のとおり。
OS : Windows2000
JDK: Sun JDK1.4.1 Beta
プリミティブ型やString型のpublic static finalなフィールドを参照
するコードをコンパイルすると、値自体がインライン化されます。
例)
public class Constants {
public static final int INT_VALUE = 123;
public static final String STRING_VALUE = "ABC";
}
public class Client {
public static void main(String[] args) {
int value = Constants.INT_VALUE;
String name = Constants.STRING_VALUE;
}
}
このコードをコンパイルしてjavapコマンドでディスアセンブルすると、
$ javap -c Client
:
Method void main(java.lang.String[])
0 sipush 789
3 istore_1
4 ldc #2 <String "XYZ">
6 astore_2
7 return
と、mainメソッドの中では値そのものが使われます。
定数を提供する側(ここではConstantsクラス)と定数を利用する側
(ここではClientクラス)が別々に開発されているような場合、定数に
変更があってもClientクラスを再コンパイルしない限り古い値を使い続
けることになります。
この辺りの仕様については、Java言語仕様の13.4.8項に述べられていま
す。
http://www.y-adagio.com/public/standards/tr_javalang2/binaryComp.
doc.html#45139
JLSでは、static finalなフィールドをpublicではなくprivateとし、こ
れをアクセッサを介して取り出すことを勧めています。
一方、タイプセーフな定数を使用すると、
public static void main(String[] args) {
Suit club = Suit.CLUBS;
:
のコードは以下のようにバイトコンパイルされます。
Method void main(java.lang.String[])
0 getstatic #17 <Field Suit CLUBS>
必ずSuitクラスに値を取りに行きます。
---
Toru TAKAHASHI
http://www.alles.or.jp/~torutk/oojava/