Java静的最終クラス変数の値をリフレクションで取り出すことはできますか?リフレクションによってJava静的最終変数値にアクセスする
32
A
答えて
55
私はそれがタイプとコンパイラによって異なりますと推測します
(2番目の考えでは、それはもっと良いことではありませんでした!)。 Sunのコンパイラはプリミティブ定数をインラインにしますが、クラスからエントリを完全に削除するかどうかはわかりません。私は見つけることができます。
編集:はい、インラインであってもアクセスできます。 Testクラス:
public class ReflectionConstantTest {
private static final int CONST_INT = 100;
private static final String CONST_STRING = "String";
private static final Object CONST_OBJECT = new StringBuilder("xyz");
public static void main(String[] args) throws Exception {
int testInt = CONST_INT;
String testString = CONST_STRING;
Object testObj = CONST_OBJECT;
for (Field f : ReflectionConstantTest.class.getDeclaredFields()) {
f.setAccessible(true);
System.out.println(f.getName() + ": " + f.get(null));
}
}
}
出力:
CONST_INT: 100 CONST_STRING: String CONST_OBJECT: xyz
javap -c
出力:
Compiled from "ReflectionConstantTest.java" public class scratch.ReflectionConstantTest extends java.lang.Object{ public scratch.ReflectionConstantTest(); Code: 0: aload_0 1: invokespecial #1; //Method java/lang/Object."":()V 4: return public static void main(java.lang.String[]) throws java.lang.Exception; Code: 0: bipush 100 2: istore_1 3: ldc #2; //String String 5: astore_2 6: getstatic #3; //Field CONST_OBJECT:Ljava/lang/Object; 9: astore_3 10: ldc_w #4; //class scratch/ReflectionConstantTest 13: invokevirtual #5; //Method java/lang/Class.getDeclaredFields:()[Ljava/lang/reflect/Field; 16: astore 4 18: aload 4 20: arraylength 21: istore 5 23: iconst_0 24: istore 6 26: iload 6 28: iload 5 30: if_icmpge 90 33: aload 4 35: iload 6 37: aaload 38: astore 7 40: aload 7 42: iconst_1 43: invokevirtual #6; //Method java/lang/reflect/Field.setAccessible:(Z)V 46: getstatic #7; //Field java/lang/System.out:Ljava/io/PrintStream; 49: new #8; //class java/lang/StringBuilder 52: dup 53: invokespecial #9; //Method java/lang/StringBuilder."":()V 56: aload 7 58: invokevirtual #10; //Method java/lang/reflect/Field.getName:()Ljava/lang/String; 61: invokevirtual #11; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 64: ldc #12; //String : 66: invokevirtual #11; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 69: aload 7 71: aconst_null 72: invokevirtual #13; //Method java/lang/reflect/Field.get:(Ljava/lang/Object;)Ljava/lang/Object; 75: invokevirtual #14; //Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder; 78: invokevirtual #15; //Method java/lang/StringBuilder.toString:()Ljava/lang/String; 81: invokevirtual #16; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 84: iinc 6, 1 87: goto 26 90: return static {}; Code: 0: new #8; //class java/lang/StringBuilder 3: dup 4: ldc #17; //String xyz 6: invokespecial #18; //Method java/lang/StringBuilder."":(Ljava/lang/String;)V 9: putstatic #3; //Field CONST_OBJECT:Ljava/lang/Object; 12: return }
あなたはCONST_INT
がインライン化されていることを見ることができますが、CONST_STRING
とCONST_OBJECT
(もちろん)がありません。まだCONST_INT
はまだ反映されています。
6
はい。 (唯一なものなどの静的、インスタンスはありません。それは、静的、非インスタンスです。)
> If the underlying field is a static field, the obj argument is ignored; it may be null.
(反射のほとんどの用途は悪い考えであることを、標準的な警告を含む)に
1
オープンの場合ソースライブラリは、あなたができる別のクラスでは
FieldUtils.readDeclaredStaticField
public class Test {
public final static String CONSTANT="myConstantValue";
}
を使用することができ、あなたのプロジェクトに許可されています
Object value = FieldUtils.readDeclaredStaticField(Test.class, "CONSTANT");
System.out.println(value);
「myConstantValue」がコンソールに表示されます。
0
名前と値を取得するだけでsetAccessible(true)は必要ありません。ここでは、インターフェイスで宣言された定数に対処しなければならないとき有用な例だと、シンボル名を欲しい:
interface Code {
public static final int FOO = 0;
public static final int BAR = 1;
}
...
try {
for (Field field : Code.class.getDeclaredFields()) {
String name = field.getName();
int value = field.getInt(null);
System.out.println(name + "=" + value);
}
}
catch (IllegalAccessException e) {
System.out.println(e);
}
関連する問題
- 1. リフレクションを使用してモデルクラスの静的変数にアクセスする
- 2. ベストプラクティス:Java静的非最終変数
- 3. 静的最終変数の値
- 4. 最終的なクラス変数をGWTで静的にする
- 5. Javaクラスの静的変数に反射的にアクセスする
- 6. Javaのリフレクションを使用して静的な最終フィールドを変更することはできませんか?
- 7. 最終(定数)インスタンス(非静的)変数は、クラス(静的)変数のように動作しますか?
- 8. Javaの親アクセス静的変数の子
- 9. 。最終的な静的変数としてのプロパティ
- 10. Eclipseで非最終的な静的変数を検索する
- 11. 静的変数にアクセスするテンプレートメソッド
- 12. JNIでネイティブコードから静的Java変数にアクセスする方法
- 13. Javaがリフレクションによるプライベートプロパティにアクセス
- 14. アクセス静的変数
- 15. 最終的な静的変数を変更してメソッドをテストする
- 16. 静的メソッドによって設定されている最終的な静的変数をモックする方法はありますか?
- 17. Javaのハッシュコードが最終的な変数
- 18. PHP:リフレクションによって静的フィールド/プロパティをリストする方法は?
- 19. Java静的初期化子とリフレクション
- 20. Powermockを使用して静的プライベート最終変数を嘲笑?
- 21. 静的な最終オブジェクトはガベージコレクタによって削除されますか?
- 22. 変数を介してクラスにアクセスする静的関数
- 23. Java静的変数がnullになる
- 24. 静的メソッドと静的変数のjava
- 25. JPA静的メタモデルクラスのメンバ変数を最終的に宣言できますか?
- 26. 静的変数値
- 27. 静的変数を非静的変数に割り当てる
- 28. 静的メンバー関数が静的専用変数にアクセスするときのリンカーエラー
- 29. 最終変数をリフレクションから保護する
- 30. 静的メソッドによって返される値は静的ですか?
これは、おかげで私の問題を解決しました!私はなぜf.setAccessible(true)を呼び出さなければならないのか不思議です。静的修飾子を最初から利用できない点は何ですか? – gsingh2011
@ gsingh2011:必要なのは、プライベート定数でさえ、リフレクションによってアクセスできることを実証することです(この例の3つの定数はprivateと宣言されていることがわかります)。パブリック定数は既にアクセス可能なため、アクセス可能に設定する必要はありません。 –
ああ、そうです。私は自分のフィールドに公開/非公開の修飾子を提供しなかったために私の問題が発生したことを認識した後、自分のコードをパッケージにリファクタリングしました。とにかく応答に感謝します。 – gsingh2011