We cannot directly access the instance variables within a static method because a static method can only access static variables or static methods.
In Java, non-static final variables can be assigned a value either in constructor or with the declaration. But, static final variables cannot be assigned value in constructor; they must be assigned a value with their declaration.
Static variables can be accessed by calling with the class name ClassName. VariableName. When declaring class variables as public static final, then variable names (constants) are all in upper case. If the static variables are not public and final, the naming syntax is the same as instance and local variables.
The static keyword means the value is the same for every instance of the class. The final keyword means once the variable is assigned a value it can never be changed.
I would guess that it depends on the type and the compiler (on second thought, it had sure better not!). Sun's compiler inlines primitive constants, but I don't know if they remove the entry from the class entirely. I'll find out.
Edit: Yes, you can still access them even if they are inlined. Test class:
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));
}
}
}
Output:
CONST_INT: 100 CONST_STRING: String CONST_OBJECT: xyz
javap -c
output:
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 }
You can see that CONST_INT
is inlined, but CONST_STRING
and CONST_OBJECT
(of course) are not. Yet CONST_INT
is still available reflectively.
Yes. (Only there is no such thing as static, instance. It's static, non-instance.)
> If the underlying field is a static field, the obj argument is ignored; it may be null.
(include standard warning that most uses of reflection are a bad idea)
If open-source libraries are allowed on your project you can use
FieldUtils.readDeclaredStaticField
public class Test {
public final static String CONSTANT="myConstantValue";
}
In another class you can use:
Object value = FieldUtils.readDeclaredStaticField(Test.class, "CONSTANT");
System.out.println(value);
You will see "myConstantValue" in the console.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With