Java可以使用反射,通过对象来获取对象所属的类的完整结构,包括:变量、方法、构造器、父类、注解和接口

以下例子我们会使用该User类进行举例:

// 实体类
class User{
    public String name;
    private int id;
    private int age;
	
	public User(){ }	

    public User(String name, int id, int age) {
        this.name = name;
        this.id = id;
        this.age = age;
    }
    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;
    }

1.获取类的名字
使用Class对象中的getName()获取包名+类名;使用getSimpleName()获取类名

public class Test04 {
    public static void main(String[] args) throws ClassNotFoundException {
        Class c1 = Class.forName("reflection.User");

        // 获取类的名字:
        System.out.println(c1.getName());   // 获取包名+类名
        System.out.println(c1.getSimpleName()); // 仅获取类名
    }
}

2.获取类的属性
使用Class对象中的getFields()来获取public属性的变量,而getDeclaredFields()可以获取全部属性,另外,使用c1.getField(String name)来获取特定的属性,当然,如果属性是私有的,则使用getDeclaredField(String name)

Class c1 = Class.forName("reflection.User");
        Field[] fields = c1.getFields();
        Field[] fields1 = c1.getDeclaredFields();
        Field name = c1.getField("name");
        Field id  = c1.getDeclaredField("id");

3.获取类的方法
使用Class对象中的getMethods()来获取public属性的方法,需要注意的是,这个方法除了会获取本类的方法,同时也会获取其继承的父类的方法。而getDeclaredtMethods()可以获取本类全部方法,不包含父类

另外,使用c1.getMethod(String name, Class[] argTypes)来获取特定的方法,name参数传入方法名,argTypes则是需要传入该方法的参数类型,因为Java中存在重载机制,如果不传入参数类型,可能会无法区分重载的各个方法

java 反射获取具体类型 java反射获取类名_构造器


4.获取指定的构造器

使用getConstructors()来获取当前对象所属类的所有的构造器,也就是获取类的构造方法,如果构造方法是私有的,那么可以使用getDeclaredConstructors()来获取

那么我们获取到这些对象之后,可以怎么使用呢?我们可以通过这些然后使用反射机制动态创建对象

// 获取User类的Class
	Class c1 = Class.forName(com.User);
	User user = (User)c1.newINstance();	//调用了User的无参构造器,类中必须要有无参构造方法

当然,上面既然介绍了如何获得构造器,那么我们也可以通过构造器创建对象。这种方法可以调用带参数的构造器动态构造方法

Constructor constructor = c1.getDeclaredConstructor(String.class, int.class, int.class);
	User user = constructor.newInstance("张三",114514,24);

除了动态创建函数,还可以动态执行方法:

// 通过反射获取方法
        Method setAge = c1.getDeclaredMethod("setAge", int.class);
        // invoke函数,用于激活一个方法
        setAge.invoke(user,24);

很显然,invoke方法除了需要传入参数之外,还需要指定该函数执行的对象是哪个

需要注意的是,反射方式相比于普通方法更加消耗资源。