Thursday, March 18, 2010

Modifying static final fields through reflection

In Java, nothing is impossible.
import java.lang.reflect.*;

public class EverythingIsTrue {
   static void setFinalStatic(Field field, Object newValue) throws Exception {
      field.setAccessible(true);

      Field modifiersField = Field.class.getDeclaredField("modifiers");
      modifiersField.setAccessible(true);
      modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);

      field.set(null, newValue);
   }
   public static void main(String args[]) throws Exception {      
      setFinalStatic(Boolean.class.getField("FALSE"), true);

      System.out.format("Everything is %s", false); // "Everything is true"
   }
}
Having fun yet?
/* 
 *  "Six by nine. Forty two."
 *  "That's it. That's all there is."
 *  "I always thought something was fundamentally wrong with the universe."
 * 
 *                       The Restaurant at the End of the Universe
 *                                                (Douglas Adams)
 */

public class UltimateAnswerToEverything {
   static Integer[] ultimateAnswer() {
      Integer[] ret = new Integer[256];
      java.util.Arrays.fill(ret, 42);
      return ret;
   }   
   public static void main(String args[]) throws Exception {
      EverythingIsTrue.setFinalStatic(
         Class.forName("java.lang.Integer$IntegerCache")
            .getDeclaredField("cache"),
         ultimateAnswer()
      );
      System.out.format("6 * 9 = %d", 6 * 9); // "6 * 9 = 42"
   }
}

3 comments:

  1. wow. Is there an emoticon for: there is no god?

    ReplyDelete
  2. This comment has been removed by the author.

    ReplyDelete
  3. You can do the same in C++ too [1].
    With dp4j 1.2 [2] the reflection code is injected if setting the final variable occurs in a @Reflect or @Test annotated method body.

    [1] http://www.cppreference.com/wiki/keywords/const_cast
    [2] http://sourceforge.net/projects/dp4j/files/1.2-SNAPSHOT/

    ReplyDelete