Java中的Class类和反射原理

术语解释:

类:可以理解为一种数据类型的定义。里面可以有成员变量和方法。
对象:可以理解为一种数据类型定义的一种实现。类的实例,占用内存区域。每个对象都是一个类的实例。
类的对象和类的实例说的其实是一种东西。


Class类:

Class<String> stringClass = String.class;
//stringClass是Class类的对象,且代表了String类
//用它的newInstance方法可以获取一个String对象
String str = stringClass.newInstance();
System.out.println(str.getClass().getName()); //输出java.lang.String

Class是一个类,这个类的每个实例代表一个类。

如,String是一个类,”abc”是类String的一个实例,
String.class(或”abc”.getClass())是Class类的一个实例,并且这个实例代表String类。

也就是说,java虚拟机中每个类都是一个对象,这些对象都是Class类的实例。


反射原理:

我们很容易就能够获取代表类的Class类型的实例对象,而这个Class类型的对象有很多方法能够帮助我们获取此对象所代表的类的信息,因此我们可以利用这个Class类型的对象来实现java的反射机制。

比如,我们定义一个类User:

public class User {
    private String name;
    private int age;
    private double money;

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }
    @Override
    public String toString() {
        return String.format("User:[name=%s, age=%s, money=%s]", name, age, money);
    }
}

如下,我们可以获取User类的成员变量,甚至可以获取User类对象的私有成员变量值:

public static void main(String[] args) throws Exception{
    User user = new User("张三", 20);
    System.out.println(user);

    Class<User> userClass = User.class;
    //通过调用表示User类的Class对象方法来获取User类的所有成员变量
    Field[] fields = userClass.getDeclaredFields();  
    for(Field field : fields){
        //获取User类此成员变量的名称和类型
        System.out.print(String.format("name:%s, type:%s | ", field.getName(), field.getType())); 
        field.setAccessible(true);  //取消此成员变量的访问检查
        System.out.println(field.get(user));//获取user对象的此成员变量值
    }
}

输出为:

User:[name=张三, age=20, money=0.0]
name:name, type:class java.lang.String | 张三
name:age, type:int | 20
name:money, type:double | 0.0

除了成员变量信息,我们还可以获取类的方法,构造函数,继承,类加载器等其他信息。

Field[] fields = userClass.getDeclaredFields();
Method[] methods = userClass.getDeclaredMethods();
Constructor<?>[] constructors = userClass.getConstructors();
Class<?> interfaces[] = userClass.getInterfaces();
Class<?> superclass = userClass.getSuperclass();
String name = userClass.getClassLoader().getClass().getName();

猜你喜欢

转载自blog.csdn.net/xuejianbest/article/details/80404848