Tag Archives: reflection

Forbidden Java actions: updating final and static final fields

by Mikhail Vorontsov

This article will discuss how you can update final or static final fields in Java. This is not allowed on the Java language level, but surprisingly, standard JDK classes will make it possible for you. Of course, we won’t forget a best Java hacker friend – sun.misc.Unsafe class from Oracle JDK. This is a second article in the “Forbidden Java actions” series started with Forbidden Java actions: object assignments, type conversions etc on the low level in Java.

Updating final or private fields

This is a simple trick. All you have to know about is a java.lang.reflect.AccessibleObject.setAccessible(boolean) method. If a field or method can not be accessed by Java language means in the current context (for example, you want to access a private field or method) – use this method with argument = true to obtain reflection access to that field or method. Unfortunately, this method is a subject of security checks, so it may be forbidden by a security manager in many enterprise server environments.

The following program will update a private final field of another class. It will print 20, despite the fact that a final field was initialized with 10 in the constructor.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class FinalPrivateField {
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
        final A instance = new A( 10 );
        B.updateA( instance, 20 );
        System.out.println( instance.getField() );
    }
 
    public static class A
    {
        private final int m_field;
 
        public A( final int field ) {
            m_field = field;
        }
 
        public int getField() {
            return m_field;
        }
    }
 
    public static class B
    {
        public static void updateA( final A other, final int newValue ) throws NoSuchFieldException, IllegalAccessException
        {
            final Field fieldA = A.class.getDeclaredField( "m_field" );
            fieldA.setAccessible( true );
            fieldA.setInt( other, newValue );
        }
    }
}
public class FinalPrivateField {
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
        final A instance = new A( 10 );
        B.updateA( instance, 20 );
        System.out.println( instance.getField() );
    }

    public static class A
    {
        private final int m_field;

        public A( final int field ) {
            m_field = field;
        }

        public int getField() {
            return m_field;
        }
    }

    public static class B
    {
        public static void updateA( final A other, final int newValue ) throws NoSuchFieldException, IllegalAccessException
        {
            final Field fieldA = A.class.getDeclaredField( "m_field" );
            fieldA.setAccessible( true );
            fieldA.setInt( other, newValue );
        }
    }
}

Continue reading