今天不知道为什么之前的笔记没保存上,好在这些反射暴破的原理基本一致,这里还有些残留,大家凑合看一下把
119.反射暴破
通过反射操作方法
public class Class01 { public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException { //1.得到Student类对应的 Class对象 Class<?> stuClass = Class.forName("class_.Student"); //2.创建对象 Object o = stuClass.newInstance();//o 的运行类型是Student System.out.println(o.getClass());//Student //3.使用反射得到 age 属性对象 Field age = stuClass.getField("age"); age.set(o, 88); System.out.println(o);//88 System.out.println(age.get(o));//返回age属性 //4.使用反射操作 name 属性 Field name = stuClass.getDeclaredField("name"); //对name进行暴破 可以操作private属性 name.setAccessible(true); name.set(o,"Alyx"); System.out.println(o); System.out.println(name.get(o)); } } class Student { public int age; private static String name; public Student(int age) {//无参 } @Override public String toString() { return "Student{" + "age=" + age +", name=" + name + '}'; } }
通过反射访问类中的成员
-
根据方法名和参数列表获取Method方法对象:Method m = clazz.getDeclaredMethod(方法名,XX.class)
-
获取对象:Object o = clazz.newInstance();
-
暴破:m.setAccessible(true)
-
访问:Object returnValue = m.invoke(o,实参列表);
-
注意:如果是静态方法,则invoke的参数o,可以写成null
public class Class01 { public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException { //1.得到Boss类对应的Class对象 Class<?> bossCls = Class.forName("class_.Boss"); //2.创建对象 Object o = bossCls.newInstance(); //3.调用public的hi方法 //Method hi = bossCls.getMethod("hi", String.class); //(1)得到hi方法对象 Method hi1 = bossCls.getDeclaredMethod("hi", String.class); //(2)调用 hi1.invoke(o, "NARUTO"); //4.调用private static 方法 //(1)得到say对象方法 Method say = bossCls.getDeclaredMethod("say", int.class, String.class, char.class); //(2)因为say方法是private,所以需要暴破 say.setAccessible(true); System.out.println(say.invoke(o, 100, "张三", '男')); //(3)因为say方法是static的,所以可以传入null System.out.println(say.invoke(null, 200, "李四", '女')); //5.在反射中,如果方法有返回值,统一返回Object,但它运行类型和方法定义的返回类型一致 Object invoke = say.invoke(null,300,"王五","男") System.out.println("reVal的运行类型是=" + reVal.getClass());//String } } class Boss{ public int age; private static String name; public Boss() { } private static String say(int n,String s,char c) { return n + " " + s + " " + c; } public void hi(String s) { System.out.println("hi " + s); } }
120.反射课后练习
//1.定义PrivateTest类,有私有name属性,并且属性值为hellokitty //2.提供getName的公有方法 //3.创建PrivateTest的类,利用Class类得到私有的name属性,修改私有的name属性,并调用getName()的方法打印name属性值 public class Class01 { public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException { //1.得到Private类对应的Class对象 Class<PrivateTest> privateTestClass = PrivateTest.class; //2.创建对象实例 PrivateTest privateTestObj = privateTestClass.newInstance(); //3.得到Name属性 Field name = privateTestClass.getDeclaredField("name"); //4.暴破name name.setAccessible(true); name.set(privateTestObj,"sadkitty"); //5.得到getName方法 Method getName = privateTestClass.getMethod("getName"); //6.调用方法 Object invoke = getName.invoke(privateTestObj); System.out.println("name属性的值=" + invoke); } } class PrivateTest{ private String name = "hellokitty"; public String getName(){ return name; } }