一般来说类的对象都是在程序运行之前就创建完成的,但是这样会很耗内存,比如在一些3A游戏中,它的环境渲染可以看作是一个对象,如果这些都是在启动阶段创建完成对电脑的要求就会非常高,所以它们采用的是实时渲染,同样的为了解决想在程序运行中可以实时创建对象,我们就要使用反射,那什么是反射。

在了解反射之前我们先来了解Class类,Class类不是关键词class,Class类是所有抽象类的类,也就是说所有的类包括我们自己定义的类,每一个类都有唯一的Class对象。

Class类的对象在我们使用类的时候就在Java虚拟机(JVM)上创建完成,换句话说只要把这个类用起来了就一定会创建Class对象。Class类对象可以获取当前类的属性(字段),方法和构造方法,获取到了构造方法就是创建类的对象了。在通过Class对象获取构造方法就可以实现实时创建对象了。

这个过程就是反射,通过Class获取构造方法,在实时获取构造方法创建对象。下面来看看如何使用代码来实现反射。

先构建一个类:

public class Student {
    private String name;
    private int age;
    public Student(){

    }
    public Student(String name,int age){
        this.name=name;
        this.age=age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
    public void getStudent(){
        System.out.println(name+"正在学习! 年龄:"+age);
    }
}

我们有三种方法获取Class对象,一个是通过直接调用类名的Class对象,一个是通过Class类的方法.forName(),在方法中添加全类名(包名+类名),还有一个是创建一个对象调用它的getClass()方法。这三种中第二种使用的最多,因为它不用担心类名重合而且也不用再创建一个对象。

Class stu1=Student.class;
try {
    Class stu2=Class.forName("com11.ThreadText.Reflect.Student");
} catch (ClassNotFoundException e) {
    throw new RuntimeException(e);
}
Class stu3=new Student().getClass();

再通过Constructor类来获取Class对象的构造方法:

   try {
            constructor = stu2.getConstructor(String.class,int.class);
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        }

最后直接通过构造方法创建对象:

   try {
            Student student=(Student) constructor.newInstance("Adam",19);
        } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
            throw new RuntimeException(e);
        }

如果是想通过Class类来访问私有对象,就先要获取权限在进行如上的操作:

 Field field= stu2.getDeclaredField("name");
        field.setAccessible(true);
        field.set(student,"Jan");

这样就改变了类对象中的私有成员了。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐