获取类中类
在AspectJWeaver
反序列化中,需要获取SimpleCache
中的私有类StorableCachingMap
目前我已知的方法有两种,第一种是比较方便的获取方法
直接SimpleCache$StorableCachingMap
表示类中类
1 2 3 4 5
| Class clazz = Class.forName("org.aspectj.weaver.tools.cache.SimpleCache$StoreableCachingMap"); Constructor constructor = clazz.getDeclaredConstructor(String.class ,int.class); constructor.setAccessible(true);
HashMap simpleCache = (HashMap) constructor.newInstance("/tmp" ,60000);
|
第二种是通过父类中的变量获取到类,相对麻烦一点
1 2 3 4 5 6 7
| Class clazz2 = SimpleCache.class; Constructor constructor1 = clazz2.getDeclaredConstructor(String.class ,boolean.class); constructor1.setAccessible(true); SimpleCache simpleCache1 = (SimpleCache) constructor1.newInstance("/tmp" ,true); Field field = clazz2.getDeclaredField("cacheMap"); field.setAccessible(true); Map map = (Map) field.get(simpleCache1);
|
关键点就是,需要将变量对应的类转化为对应的,也就是需要将其转为Map
类型

不使用构造方法创建对象
核心是使用ReflectionFactory
链接
Java8
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 31 32
| package Seri.ReflectDemo;
import sun.reflect.ReflectionFactory; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException;
public class ReflectionFactoryDemo { public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { ReflectionFactory reflectionFactory = ReflectionFactory.getReflectionFactory(); Constructor<Object> constructor = Object.class.getDeclaredConstructor(); Constructor<?> constructorForSerialization = reflectionFactory .newConstructorForSerialization(User.class, constructor); constructorForSerialization.setAccessible(true); System.out.println(constructorForSerialization.newInstance()); }
public static class User { private String name = "lisi"; public User() { System.out.println("User created"); } @Override public String toString() { return "user=" + name; } } }
|
Java11
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 31 32 33 34 35 36 37 38 39 40 41
| import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method;
public class TestReflectionFactory { public static void main(String[] args) throws InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchMethodException, ClassNotFoundException { Constructor<?> constructor = newConstructorForSerialization(User.class, getJavaLangObjectConstructor()); System.out.println(constructor.newInstance()); }
public static class User { private String name = "lisi"; public User() { System.out.println("User created"); } @Override public String toString() { return "user=" + name; } }
public static <T> Constructor<T> newConstructorForSerialization(Class<T> type, Constructor<?> constructor) throws ClassNotFoundException, InvocationTargetException, NoSuchMethodException, IllegalAccessException { Class<?> reflectionFactoryClass = getReflectionFactoryClass(); Object reflectionFactory = createReflectionFactory(reflectionFactoryClass); Method newConstructorForSerializationMethod = getNewConstructorForSerializationMethod(reflectionFactoryClass); return (Constructor) newConstructorForSerializationMethod.invoke(reflectionFactory, type, constructor); } private static Class<?> getReflectionFactoryClass() throws ClassNotFoundException { return Class.forName("sun.reflect.ReflectionFactory"); } private static Object createReflectionFactory(Class<?> reflectionFactoryClass) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { Method method = reflectionFactoryClass.getDeclaredMethod("getReflectionFactory"); return method.invoke((Object) null); } private static Method getNewConstructorForSerializationMethod(Class<?> reflectionFactoryClass) throws NoSuchMethodException { return reflectionFactoryClass.getDeclaredMethod("newConstructorForSerialization", Class.class, Constructor.class); } private static Constructor<Object> getJavaLangObjectConstructor() throws NoSuchMethodException { return Object.class.getConstructor((Class[]) null); } }
|
反射修改父类中的属性
Hibernate1
这条链中,
PojoComponentTuplizer
是AbstractComponentTuplizer
的子类,但是PojoComponentTuplizer
中调用了很多父类的属性,所以需要修改父类中的变量
由于反射是直接修改内存中的属性,所以可以直接修改AbstractComponentTuplizer
中的属性
像这样(伪代码
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 31 32 33 34 35 36
| import java.lang.reflect.Field;
class AbstractComponentTuplizer { private String value = "Parent Value";
public String getValue() { return value; } }
class PojoComponentTuplizer extends AbstractComponentTuplizer { }
public class Main { public static void main(String[] args) throws Exception { PojoComponentTuplizer tuplizer = new PojoComponentTuplizer();
System.out.println("Before modification: " + tuplizer.getValue());
Class<?> parentClass = AbstractComponentTuplizer.class;
Field valueField = parentClass.getDeclaredField("value");
valueField.setAccessible(true);
valueField.set(tuplizer, "Modified Value");
System.out.println("After modification: " + tuplizer.getValue()); } }
|
反射修改HashSet中唯一值
只能修改容量为一的HashSet对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| HashSet hashSet = new HashSet(1); hashSet.add("xxx");
Field setMap = hashSet.getClass().getDeclaredField("map"); setMap.setAccessible(true); HashMap hashMap = (HashMap) setMap.get(hashSet); Field setTable = hashMap.getClass().getDeclaredField("table"); setTable.setAccessible(true); Object[] table = (Object[]) setTable.get(hashMap); Object Node = table[1]; Field setKey = Node.getClass().getDeclaredField("key"); setKey.setAccessible(true);
setKey.set(Node, tiedMapEntry);
|