Last active
October 23, 2022 05:21
-
-
Save nishidy/90decf4a18544844dfd8 to your computer and use it in GitHub Desktop.
Java reflection/unsafe
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.lang.reflect.Constructor; | |
import java.lang.reflect.Method; | |
import java.lang.reflect.Field; | |
import sun.misc.Unsafe; | |
class S { | |
private void privatePrintS () { System.out.println("This is in S."); }; | |
public void publicPrintS () { System.out.println("This is in S."); }; | |
} | |
class A extends S { | |
private static final Integer publicFinalInt = 100; | |
public String publicString; | |
public int publicInt; | |
public int publicInt2; | |
public int publicInt3; | |
private A(String argString){ | |
this.publicString = argString; | |
}; | |
private void privatePrintA () {}; | |
public A(int argInt){ | |
this.publicInt = argInt; | |
}; | |
public A(){}; | |
public void publicPrintA () {}; | |
static void showPublicFinalInt(){ | |
System.out.println(publicFinalInt); | |
} | |
} | |
//@SuppressWarnings("all") | |
class ReflectionTest { | |
public static void main(String argv[]) throws Exception{ | |
Class classA = A.class; | |
A instanceA = A.class.newInstance(); | |
instanceA = A.class | |
.getConstructor(int.class) | |
.newInstance(10); | |
Class<?>[] params = { String.class }; | |
Constructor<A> constructor = A.class | |
.getDeclaredConstructor(params); | |
constructor.setAccessible(true); | |
instanceA = constructor | |
.newInstance(new String("instance of class A")); | |
System.out.println( "[getMethods]" ); | |
for( Method method: instanceA.getClass().getMethods() ){ | |
System.out.print( method.getName() + ": " ); | |
for( Class<?> c : method.getParameterTypes() ){ | |
System.out.print( c.getName() + " " ); | |
} | |
System.out.println( "" ); | |
} | |
System.out.println( "[getDeclaredMethods]" ); | |
for( Method method: instanceA.getClass().getDeclaredMethods() ){ | |
System.out.println( method.getName() + ": " ); | |
for( Class<?> c : method.getParameterTypes() ){ | |
System.out.println( c.getName() + " " ); | |
} | |
System.out.println( "" ); | |
} | |
if(classA == instanceA.getClass()){ | |
System.out.println("classA and instanceA.getClass() are the same."); | |
}else{ | |
System.out.println("classA and instanceA.getClass() are NOT the same."); | |
} | |
Field f = Unsafe.class.getDeclaredField("theUnsafe"); | |
f.setAccessible(true); | |
Unsafe unsafe = (Unsafe) f.get(null); | |
A.showPublicFinalInt(); | |
Field fld = A.class.getDeclaredField("publicFinalInt"); | |
f.setAccessible(true); | |
// unboxing works | |
unsafe.putObject(unsafe.staticFieldBase(fld),unsafe.staticFieldOffset(fld),200); | |
A.showPublicFinalInt(); | |
unsafe.putObject(unsafe.staticFieldBase(fld),unsafe.staticFieldOffset(fld),new Integer(300)); | |
A.showPublicFinalInt(); | |
f = A.class.getDeclaredField("publicInt"); | |
System.out.println(unsafe.objectFieldOffset(f)); | |
f = A.class.getDeclaredField("publicString"); | |
System.out.println(unsafe.objectFieldOffset(f)); | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment