final Member nach Initialisierung aendern?!

Thomas Darimont

Erfahrenes Mitglied
Hallo!

let's do some black magic ;)
Code:
  package de.tutorials;
  
  import java.lang.reflect.Field;
  
  import sun.misc.Unsafe;
  
  public class VeryDirtyFinalFieldChangeExample {
  
  	/**
  	 * @param args
  	 */
  	public static void main(String[] args) throws Exception {
  
  		SomeObject o = new SomeObject("Hallo");
  		System.out.println(o);
  		Field field = SomeObject.class.getDeclaredField("str");
  
  		Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
  		theUnsafe.setAccessible(true);
  
  		Unsafe unsafe = (Unsafe) theUnsafe.get(null);
  
  		long fieldOffset = unsafe.fieldOffset(field);
  		unsafe.putObject(o, fieldOffset, "FOO");
  
  		System.out.println(o);
  	}
  
  	static class SomeObject {
  		final String str;
  
  		public SomeObject(String str) {
  			this.str = str;
  		}
  
  		public String toString() {
  			return super.toString() + " " + this.str;
  		}
  	}
  }

... geht witzigerweise auch per Reflection:
Code:
/**
 * 
 */
package de.tutorials;

import java.lang.reflect.Field;

/**
 * @author Thomas.Darimont
 *
 */
public class FinalFieldSetExample {

	private final Object OBJECT = new Object();
	
	/**
	 * @param args
	 */
	public static void main(String[] args) throws Throwable{
		FinalFieldSetExample finalFieldSetExample = new FinalFieldSetExample();
		System.out.println(finalFieldSetExample.OBJECT);
		Field field = FinalFieldSetExample.class.getDeclaredField("OBJECT");
		field.setAccessible(true);
		field.set(finalFieldSetExample, "BUBU");
		System.out.println(finalFieldSetExample.OBJECT);
	}
}

aber nur für finale Instanz member. Klassen member können damit nicht ersetzt werden.

Gruss Tom
 
Üble Klasse.. Die hätte man mal lieber non-public gemacht ;) (Obwohl ich seh grad du hast das ja mit Reflection gemacht.. ginge das auch ohne?)

Mit folgende Methoden lässt sich bestimmt auch allerlei Unsinn anstellen :) (Ob es da ein Exploit gibt ;) Mal austesten)

Code:
public native long getAddress(long l);
 
public native void putAddress(long l, long l1);
 
public native long allocateMemory(long l);
 
public native long reallocateMemory(long l, long l1);
 
public native void setMemory(long l, long l1, byte byte0);
 
public native void copyMemory(long l, long l1, long l2);
 
public native void freeMemory(long l);
 
Zuletzt bearbeitet:
Zurück