反射的使用学习
如何获取类的结构信息:
//1 获取class对象
Class c = Class.forName("com.oop.demo07.Student");
//2 获取成员属性
Field[] fields = c.getFields(); //获取全部非私有成员属性,返回Field数组
Field[] fields = getDeclaredFields(); //获取全部成员属性(包括私有),返回Field数组
Field field = getField(指定属性名); //获取指定属性,返回Field(不返回私有属性)
Field field = getDeclaredField(指定属性名); //获取指定属性的值 ,返回Field
//3.获取成员方法 (获取全部方法,同理参考成员属性)
Method[] methods = c.getMethods();
Method[] methods = c.getDeclaredMethods();
Method method= c.getMethod(方法名,参数类型.class);
Method method= c.getDeclaredMethod(方法名,参数类型.class);
//4.获取构造器
Constructor[] constructors = c.getConstructors;//获取全部非私有构造器,参考上面
Constructor[] constructors = c.getDeclaredConstructors();//获取全部构造器,参考上面
Constructor constructor = c.getConstructor(参数类型.class);
Constructor constructor = c.getDeclaredConstructor(参数类型.class);
//为什么要获取方法和构造器需要加入参数
//原因:因为方法和构造器都可能会出现方法重载,所以必须要加入参数类型,才能准确获取目标方法、构造器
动态创建对象执行方法:
-
创建对象:
- 无参构造 : newInstance()方法
- 有参构造:不能直接用Class对象的 newInstance()方法,要先获取指定构造器对象,再传参构造
-
调用方法:
- 通过class对象获取Method方法对象(见上)
- 激活:invoke(Object o , 参数)方法执行必须用invoke激活,传入对象,参数
- 调用私有方法,必须开启权限setAccessible(true)方法
-
调用属性:
- 通过class对象获取Field对象(见上)
- 调用Field对象的set(Object o , 参数)方法设置属性,传入对象,参数
- 修改私有属性,必须开启权限setAccessible(true)方法
参考代码:
package com.reflection;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Objects;
public class Demo08 {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
Class c = Class.forName("com.reflection.User");
//无参构造
User user1 = (User) c.newInstance();//1.父类转子类(高转低)必须要加(类型)强转 2. 本质调用无参构造器
System.out.println(user1);
//有参构造,不能直接用Class,要先获取指定构造器对象,再传参构造
Constructor Constructor = c.getDeclaredConstructor(String.class, int.class, int.class);
User user2 = (User) Constructor.newInstance("AAA", 001,18);
System.out.println(user2);
//通过反射调用方法
User user3 = (User) c.newInstance();
Method setName = c.getMethod("setName", String.class);
setName.invoke(user2,"user2");
setName.invoke(user3,"user3");
System.out.println(user1.getName());
System.out.println(user2.getName());
System.out.println(user3.getName());
//通过反射操作属性,不能直接操作私有属性,需要赋予访问权限(安全检查)
User user4 = (User) c.newInstance();
Field name = c.getDeclaredField("name");
name.setAccessible(true);//如果是私有属性,需要设置访问权限
name.set(user4,"user4-test");
System.out.println(user4.getName());
}
}
class User{
private String name ;
private int id;
private int age;
public User(String name, int id, int age) {
this.name = name;
this.id = id;
this.age = age;
}
public User() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", id=" + id +
", age=" + age +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return id == user.id && age == user.age && Objects.equals(name, user.name);
}
@Override
public int hashCode() {
return Objects.hash(name, id, age);
}
}

浙公网安备 33010602011771号