反射的三个对象
Field
获取成员变量们
//获取所有的成员变量,只能是public的
* Field[] getFields()
//获取指定名称的成员变量,只能是public的
* Field getField(String name)
//获取所有的成员变量,包括私有的
* Field[] getDeclaredFields()
//获取指定名称的成员变量,包括私有的
* Field getDeclaredField(String name)
获取变量的类型
Field[] fields = Aaaa.class.getDeclaredFields();
for (Field field : fields) {
Class<?> type = field.getType();
System.out.println(type);
//判断它是不是String类型
if(type==String.class) {
System.out.println("String");
}
}
设置变量值
User user=new User();
//获取所有属性值
Field[] fields = user.getClass().getDeclaredFields();
//循环属性
for (Field field : fields) {
//设置取消java语言检查,才能设置值
field.setAccessible(true);
//判断属性名是不是id,如果是的话,设置它的值
if("id".equals(field.getName()))
field.set(user,4L);
}
Constructor
获取构造方法
//获取无参的构造方法,只能是Public的
* Constructor<?>[] getConstructors()
//获取对应参数的有参构造方法,只能是public的
* Constructor<T> getConstructor(类<?>... parameterTypes)
//获取有参的构造方法,包括私有的
* Constructor<T> getDeclaredConstructor(类<?>... parameterTypes)
//获取所有的构造方法,包括私有的
* Constructor<?>[] getDeclaredConstructors()
Method
获取成员方法
//获取所有成员方法,只能是public的
* Method[] getMethods()
//获取方法名为name的指定参数的方法,只能是public的
* Method getMethod(String name, 类<?>... parameterTypes)
//获取所有的成员方法,包括私有的
* Method[] getDeclaredMethods()
//获取方法名为name的指定参数的方法,包括私有的
* Method getDeclaredMethod(String name, 类<?>... parameterTypes)
setAccessible
只有设置setAccessible
的值为true,才能获取私有的方法或者变量或者构造方法,如果不设置的话会报错IllegalAccessException
,但是有安全漏洞,能不使用就不要使用,安全检测会报缺陷
获取class对象的方式
/**
获取Class对象的方式:
1. Class.forName("全类名"):将字节码文件加载进内存,返回Class对象
2. 类名.class:通过类名的属性class获取
3. 对象.getClass():getClass()方法在Object类中定义着。
*/
public static void main(String[] args) throws Exception {
//1.Class.forName("全类名")
Class cls1 = Class.forName("cn.itcast.domain.Person");
System.out.println(cls1);
//2.类名.class
Class cls2 = Person.class;
System.out.println(cls2);
//3.对象.getClass()
Person p = new Person();
Class cls3 = p.getClass();
System.out.println(cls3);
//== 比较三个对象
System.out.println(cls1 == cls2);//true
System.out.println(cls1 == cls3);//true
Class c = Student.class;
System.out.println(c == cls1);
}
获取成员变量
拿到变量,自然就是设值和取值,通过get取值,set设值
public static void main(String[] args) throws Exception {
//0.获取Person的Class对象
Class personClass = Person.class;
/*
1. 获取成员变量们
* Field[] getFields()
* Field getField(String name)
* Field[] getDeclaredFields()
* Field getDeclaredField(String name)
*/
//1.Field[] getFields()获取所有public修饰的成员变量
Field[] fields = personClass.getFields();
for (Field field : fields) {
System.out.println(field);
}
System.out.println("------------");
//2.Field getField(String name)
Field a = personClass.getField("a");
//获取p对象中成员变量a 的值
Person p = new Person();
Object value = a.get(p);
System.out.println(value);
//设置p对象中a的值
a.set(p,"张三");
System.out.println(p);
System.out.println("===================");
//Field[] getDeclaredFields():获取所有的成员变量,不考虑修饰符
Field[] declaredFields = personClass.getDeclaredFields();
for (Field declaredField : declaredFields) {
System.out.println(declaredField);
}
//Field getDeclaredField(String name)
Field d = personClass.getDeclaredField("d");
//忽略访问权限修饰符的安全检查,如果不设置,获取会报错
d.setAccessible(true);//暴力反射
Object value2 = d.get(p);
System.out.println(value2);
}
获取构造方法
构造方法它的作用就是创建对象,获取了构造方法,就能创建对象了。
newInstance:创建对象,有参数就是通过它的有参构造方法创建,如果没有参数,就是通过它的无参构造方法创建。
无参创建也可以通过class.newInstance简化创建
public static void main(String[] args) throws Exception {
//0.获取Person的Class对象
Class personClass = Person.class;
/*
2. 获取构造方法们
* Constructor<?>[] getConstructors()
* Constructor<T> getConstructor(类<?>... parameterTypes)
* Constructor<T> getDeclaredConstructor(类<?>... parameterTypes)
* Constructor<?>[] getDeclaredConstructors()
*/
//Constructor<T> getConstructor(类<?>... parameterTypes),获取第一个参数为String,第二个参数为int的构造器
Constructor constructor = personClass.getConstructor(String.class, int.class);
System.out.println(constructor);
//创建对象
Object person = constructor.newInstance("张三", 23);
System.out.println(person);
System.out.println("----------");
Constructor constructor1 = personClass.getConstructor();
System.out.println(constructor1);
//无参的构造方法创建对象
Object person1 = constructor1.newInstance();
System.out.println(person1);
//简化创建一个无参的构造方法,class.newInstance
Object o = personClass.newInstance();
System.out.println(o);
//constructor1.setAccessible(true);
}
获取成员方法
方法自然就是用来执行的,通过getMethod拿到指定的方法名,再通过invoke来执行它的方法
public static void main(String[] args) throws Exception {
//0.获取Person的Class对象
Class personClass = Person.class;
/*
3. 获取成员方法们:
* Method[] getMethods()
* Method getMethod(String name, 类<?>... parameterTypes)
* Method[] getDeclaredMethods()
* Method getDeclaredMethod(String name, 类<?>... parameterTypes)
*/
//获取指定名称的方法
Method eat_method = personClass.getMethod("eat");
Person p = new Person();
//执行方法,这个方法没有参数,就直接执行方法
eat_method.invoke(p);
//获取名为eat的,有一个String参数的方法
Method eat_method2 = personClass.getMethod("eat", String.class);
//执行方法,有参数的方法,就传入参数
eat_method2.invoke(p,"饭");
System.out.println("-----------------");
//获取所有public修饰的方法
Method[] methods = personClass.getMethods();
for (Method method : methods) {
System.out.println(method);
String name = method.getName();
System.out.println(name);
//method.setAccessible(true);
}
//获取类名
String className = personClass.getName();
System.out.println(className);//cn.itcast.domain.Person
}
调用静态方法
报错java.lang.IllegalAccessException: Class XX can not access a member of class XXX with modifiers "private static"
参数1设置为null
eat_method2.invoke(null,"饭");