Tuesday, March 2, 2010

Kidnapping an inner class instance

This blew my mind. Although I suppose this naturally follows from the fact that Java's final fields aren't:
import java.lang.reflect.*;

public class Me {
    final String name;

    Me(String name) {
        this.name = name;
    }

    class InnerMe {
        void whoAreYou() {
            System.out.println(name);
        }
    }
    
    InnerMe innerSelf() {
        return new InnerMe();
    }

    public static void main(String args[]) throws Exception {
        final Me me = new Me("Just the old me!");
        final InnerMe innerMe = me.innerSelf();

        innerMe.whoAreYou(); // "Just the old me!"

        Field outerThis = innerMe.getClass().getDeclaredFields()[0];
        outerThis.setAccessible(true);
        outerThis.set(innerMe, new Me("New and improved me!"));

        innerMe.whoAreYou(); // "New and improved me!"
    }
}

No comments:

Post a Comment