反射
1:类对象和它的三种获取方式
1.1 通过对象.getClass()方法
//能直接得到这个类的对象,就可以使用这种方法来通过对象获取
Person p = new Person();
Class cls1 = p.getClass();
1.2.通过类名.class 来获取字节码对象
//当前类与这个类在一块(同包),可以使用这种方法
Person p = new Person();
Class cls2 = Person.class;
//.class在jvm中只有一个,所以相等
System.out.println(cls1 == cls2);//true
1.3.通过静态方法来获取对象
//只知道这个类的类全名是,可以使用这种方法获取
try {
//通过一个类的类全名获取字节码对象
Class cls3 = Class.forName("package com.qianfeng.zjh.am.fanshe.Person");
System.out.println(cls1 == cls3); //true
}
2:通过反射获取构造器与对象实例
import java.lang.reflect.Constructor;
public class Demo2 {
//一个一个精准获取
public static void main(String[] args) throws Exception {
Class cls1 = Person.class;
//1.获取公共的构造器,没有参数
//获取默认的无参的构造器,创建对象
Person p1 = (Person) cls1.newInstance();
//无参的
Constructor constructor = cls1.getConstructor();
Person p2 = (Person) constructor.newInstance();
//2.获取带参的构造器
Constructor constructor2 = cls1.getConstructor(int.class);
//使用带参的构造器实例,指定参数,实例化一个对象
Person p3 = (Person) constructor2.newInstance(5);
Constructor constructor3 = cls1.getConstructor(int.class,String.class);
Person p4 = (Person) constructor3.newInstance(5,"jack");
}
}
3:获取私有构造器,并且能够实例化对象
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class Demo3 {
public static void main(String[] args) {
// 获取私有构造器,并且能够实例化对象
Class cls1 = Person.class;
try {
// 得到一个被任一修饰符修饰过的构造器
Constructor declaredConstructor = cls1.getDeclaredConstructor(String.class);
// 如果通过反射去破解我们私有属性,构造器,方法。就必须要破解它的权限
declaredConstructor.setAccessible(true);
Person p = (Person) declaredConstructor.newInstance("jack");
System.out.println(p);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
3:通过反射获取属性并修改值
访问一个私有的属性,并修改私有属性的值,
import java.lang.reflect.Field;
public class Demo3 {
public static void main(String[] args) throws Exception {
// 修改私有属性的值,访问一个私有的属性
Class cls1 = Person.class;
// 得到一个属性
Field declaredField = cls1.getDeclaredField("age");
declaredField.setAccessible(true);
// 属性和方法,必须依赖于一个对象来进行访问
Person p1 = (Person) cls1.newInstance();
// 使用属性去得到p1对象的值,
int int1 = declaredField.getInt(p1);
System.out.println(int1);
// 得到一个对象
// System.out.println(declaredField.get(p1));
// 修改属性值
declaredField.set(p1, 100);
// 修改之后的值
declaredField.get(p1);
System.out.println();
}
}
4:通过反射获取方法
调用带参方法
import java.lang.reflect.Method;
public class Demo3 {
//获取带参方法
public static void main(String[] args) throws Exception {
Class cls1 = Person.class;
//获取方法
Method declaredMethod = cls1.getDeclaredMethod("plus",int.class,int.class);
//需要对象调用这个方法
Object obj = cls1.newInstance();
//破解
declaredMethod.setAccessible(true);
//得到的是两个参数的方法,调用时也必须传两个参数
//接收返回值
Object abc = declaredMethod.invoke(obj,10,20);
System.out.println(abc);
}
}