reflect反射机制

1.首先了解什么是Class对象:Class 类的实例表示正在运行的 Java 应用程序中的类和接口。枚举是一种类,注释是一种接口。每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。基本的 Java 类型(booleanbytecharshortintlongfloatdouble)和关键字 void 也表示为 Class 对象。Class类封装一个对象和接口运行时的状态,当装载类时,Class类型的对象自动创建。

  • 环境:创建一个User类
public class User {
    private String username;
    private String password;
    public int id;
    //包括有参数构造方法,无参数构造方法,
    public User(String username, String password) {
        this.username = username;
        this.password = password;
    }
    
    public User() {
    }
    //公有方法、私有方法
    private void m(){
        System.out.println("私有方法");
    }
    public void m1(int id){
        System.out.println("公有方法");
    }
    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "User [username=" + username + ", password=" + password + "]";
    }

}

目录结构:

                 image

Class对象的3中创建方式:

  • 如果一个类没有被加载到虚拟机下
Class clazz1 =  Class.forName("domain.User");
  • 如果一个类被加载了,但是这个类并没有被Java虚拟机构建对象
Class clazz2 = User.class;
  • 如果在已知道一个对象的情况下获取
User user=new User();
Class clazz3 = user.getClass();

2.接下来看看这个Class对象有什么卵用。

首先可以使用getMethods(),查看所有public公有方法;

Class clazz1 =  Class.forName("domain.User");
        Method[] methods = clazz1.getMethods();
        for(Method m:methods){
            System.err.println(m);
        }

结果:包括其继承父类的所有public方法都可以拿到,构造方法不行。

public java.lang.String domain.User.toString()
public void domain.User.m1(int)
public java.lang.String domain.User.getUsername()
public void domain.User.setUsername(java.lang.String)
public java.lang.String domain.User.getPassword()
public void domain.User.setPassword(java.lang.String)
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()

然后使用一波:getDeclaredMethods();

Method[] privateMethods = clazz1.getDeclaredMethods();
         for(Method m : privateMethods){
         System.out.println(m);
         }

结果:获取该类的公有私有方法(构造除外),包括重写的方法,没写的就没有了,说白了就是获得大纲里列举的所有方法。

public java.lang.String domain.User.toString()
private void domain.User.m()
public void domain.User.m1(int)
public java.lang.String domain.User.getUsername()
public void domain.User.setUsername(java.lang.String)
public java.lang.String domain.User.getPassword()
public void domain.User.setPassword(java.lang.String)

同理,我们可以使用没有带s的该方法进行获取单个方法。

User user=new User();
        Class clazz1 =  Class.forName("domain.User");
        Method method = clazz1.getMethod("setUsername", String.class);
        method.invoke(user, "张三");
        System.out.println(user.toString());
        
        结果:User [username=张三, password=null, id=0]
User user=new User();
        Class clazz1 =  Class.forName("domain.User");
        Method m = clazz1.getDeclaredMethod("m");
        //如果对一个私有的方法进行调用,那么我们应该呀先压制访问控制权限进行访问
        m.setAccessible(true);
        m.invoke(user);

同理获得方法也差不多

User user=new User();
Class clazz1 =  Class.forName("domain.User");
//如果要获取所有的方法(包含了父类继承的方法,和自身的方法)
Field[] fields = clazz1.getFields();
//如果要获取所有的方法,包含所有的私有的方法,但是并不包含父类继承的方法
Field[] declaredFields = clazz1.getDeclaredFields();
for(Field f:declaredFields){
    System.out.println(f);
}

获取构造方法

User user=new User();
        Class clazz1 =  Class.forName("domain.User");
        Constructor[] constructors = clazz1.getConstructors();
        for(Constructor c:constructors){
            System.out.println(c);
        }
        
        Constructor constructor = clazz1.getConstructor(String.class,String.class);
        System.err.println(constructor);
        //可以通过构造方法和Class对象获得实例
        User user1 = (User) clazz1.newInstance();
        System.out.println(user1.toString());
        
        User user2 = (User) constructor.newInstance("2dssd","w2ssd");
        System.out.println(user2.toString());
原文地址:https://www.cnblogs.com/lq625424841/p/7201042.html