Я думаю, это зависит от типа и компилятора (если подумать, лучше бы не было!) Компилятор Sun указывает примитивные константы, но я не знаю, полностью ли они удаляют запись из класса. Я узнаю.
Редактировать: Да, вы все равно можете получить к ним доступ, даже если они встроены. Тестовый класс:
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
все еще доступен с отражением.