简体   繁体   中英

Setting private static final field with reflection

Based on Change private static final field using Java reflection , I tried to set a private static final field.

(I know this is terribly hacky, but this question is not about code quality; it's about Java reflection.)

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

class Main {

  static class Foo {
    private static final int A = 1;

    int getA() {
      return A;
    }
  }

  public static void main(String[] args) throws Exception {
    Field modifiers = Field.class.getDeclaredField("modifiers");
    modifiers.setAccessible(true);

    Field field = Foo.class.getDeclaredField("A");
    field.setAccessible(true);
    modifiers.setInt(field, field.getModifiers() & ~Modifier.FINAL);
    field.set(null, 2);

    System.out.println(new Foo().getA()); // should print 2
  }

}

This prints

1

I've tried this with OpenJDK 6 and 7, and Oracle 7.

I don't know what guarantees Java reflection gives. But if it failed, I thought there would be an Exception (practically all the reflection methods throw exceptions).

What is happening here?

Java inlines final fields that are initialized to constant expressions at compile time.

According to the Java Language Specification, any static final * field initialized with an expression that can be evaluated at compile time must be compiled to byte code that "inlines" the field value. That is, no dynamic link will be present inside class Main telling it to obtain the value for A from InterfaceA at runtime.

Decompile the bytecode and you'll find that the body of getA() simply pushes the constant 1 and returns it.


* - The JavaWorld quote says static final . Kumar points out that the static is not required by the language specification in the definition of a constant variable . I think Kumar is right and JavaWorld is in error.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM