各自努力,最高处见!加油!
反射(五)反射爆破
一、反射爆破创建实例(调用private修饰的构造器)
1、方式一:调用类中的public修饰的无参构造器
2、方式二:调用类中指定构造器
3、Class类相干方法
- newInstance:调用类中的无参构造器,获取对应类的对象
- getConstructor(Class…clazz):根据参数列表,获取对应的构造器对象,省略号表示可以获取多个构造器对象
- getDecalaredConstructor(Class…clazz):根据参数列表,获取对应的构造器对象
4、Constructor类相关方法
- setAccessible:爆破
- newInstance(Object…obj):调用构造器来创造对象(相当于new),可以指定构造器的实参是什么。
二、通过反射访问类中的变量
1、根据属性名获取Field对象
Field f=clazz对象.getDeclaredField("属性名");
可以获取到private属性,但是不能访问
2、爆破
f.setAccessible(true);//f是Field对象
3、访问
f.set(o,值);//o表示对象
syso(f.get(o));
如果是静态属性,则set和get中的参数o,可以写成null。
示例代码:
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
public class ReflecAccessProperty {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Class<?> studentClass = Class.forName("reflection.Student");//获取student类的Class类
Constructor<?> declaredConstructor = studentClass.getDeclaredConstructor();//获取无参构造器
Object o = declaredConstructor.newInstance();
Field declaredField = studentClass.getDeclaredField("age");//获取成员变量age的Class类
declaredField.set(o,90);
Object age_o = declaredField.get(o);
System.out.println(age_o);
Field declaredField2 = studentClass.getDeclaredField("name");//获取成员变量name的Class类,private 类型的变量需要先进行爆破
declaredField2.setAccessible(true);
declaredField2.set(null,"牛牛");
Object name_static = declaredField2.get(null);
System.out.println(name_static);
}
}
class Student {//类
public int age=10;
private static String name="xmt";
public Student() {//构造器
}
public String toString() {
return "Student [age=" + age + ", name=" + name + "]";
}
}
三、通过反射访问类中的方法
1、根据方法名和参数列表获取Method方法对象:
Method m=clazz.getDeclaredMethod(方法名,XX.class);//可以得到本类所有类型方法
2、获取对象:
Object o=clazz.newInstance();
3、爆破:m.setAccessible(true);
4、访问:Object returnValue=m.invoke(o,实参列表)
5、注意:如果是静态方法,则invoke的参数o,可以写成null!
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class ReflecAccessMethod {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Class<?> bossClass = Class.forName("reflection.Boss");
Constructor<?> declaredConstructor = bossClass.getDeclaredConstructor();
Object o = declaredConstructor.newInstance();
Method hiClass = bossClass.getDeclaredMethod("hi", String.class);//得到hi方法的对象
hiClass.invoke(o,"xmt");//调用public方法
Method say = bossClass.getDeclaredMethod("say", int.class, String.class, char.class);
say.setAccessible(true);
Object invoke = say.invoke(null, 10, "xmt", 'a');//调用静态的私有方法
System.out.println(invoke);
}
}
class Monster {}
class Boss {//类
public int age;
private static String name;
public Boss() {//构造器
}
public Monster m1() {
return new Monster();
}
private static String say(int n, String s, char c) {//静态方法
return n + " " + s + " " + c;
}
public void hi(String s) {//普通public方法
System.out.println("hi " + s);
}
}