简单介绍java中的反射

基本概念

能够分析类能力的程序成为反射;反射的功能极其强大;可以用它来分析动态运行时的类的信息。

Class类

Class类用于保存一个类的基本信息,例如属性和方法,构造器。下面简单介绍一下获取Class类实例的三种方式:
(1)Object类中的getClass()方法
通过调用Object类中的getClass()方法可以获取该类Class对象,因为Object类是所有类的父类,所以每个子类的实例都可以调用这个方法获取Class类。

		Object object = new Object();
        Class clazz = object.getClass();

(2)通过Class.forName()即Class类的forName()静态方法获取Class类。使用这种方式需要处理异常,即类找不到异常。

		try {
            Class clazz = Class.forName("java.lang.Object");
        }catch (ClassNotFoundException exception) {
            exception.getStackTrace();
        }

(3)通过 类.class 这种方式获取Class类

Class clazz = Object.class;

Class类中的基本方法

我们可以通过以上三种方式中的任意一种获取类的Class类,接下来我们简单介绍Class类中的一些信息:
(1)获取Class类中的Field

  • getFields()方法:获取本类及其父类中的所有使用public修饰的属性
  • getDeclaredFields()方法:获取本类所有的属性
		Class clazz = Object.class;
        // 获取本类及其父类中所有使用public修饰的属性
        Field[] pubFields = clazz.getFields();
        for (Field field : pubFields) {
            System.out.print(field + ";");
        }
        // 获取本类所有的属性
        Field[] allFields = clazz.getDeclaredFields();
        for (Field field : allFields) {
            System.out.print(field + ";");
        }

(2)获取Class类中的Constructor

  • getConstructors()方法:获取本类及其父类中的所有使用public修饰的构造器
  • getDeclaredConstructors()方法:获取本类所有的构造器
		Class clazz = Object.class;
		// 获取本类及其父类中所有使用public修饰的构造器
        Constructor[] pubConstructors = clazz.getConstructors();
        for (Constructor constructor : pubConstructors) {
            System.out.println(constructor.getName() + ";" + constructor.getParameterCount());
        }
        // 获取本类所有的构造器
        Constructor[] allConstructors = clazz.getDeclaredConstructors();
        for (Constructor constructor : allConstructors) {
            System.out.println(constructor.getName() + ";" + constructor.getParameterCount());
        }

(3)获取Class类中的Method

  • getMethods()方法:获取本类及其父类中的所有使用public修饰的方法
  • getDeclaredMethods()方法:获取本类所有的构造方法
		Class clazz = Object.class;
        Method[] pubMethods = clazz.getMethods();
        for (Method method : pubMethods) {
            System.out.println(method.getName() + ";");
        }
        Method[] allMethods = clazz.getDeclaredMethods();
        for (Method method : allMethods) {
            System.out.println(method.getName() + ";");
        }

(4)通过反射创建类的实例

  • newInstance()方法:获取类的实例
  • getConstructors(参数类型) / getDeclaredConstructors(参数类型) . newInstance(参数类型的值) :通过类的带参数的构造器获取实例
    注意:参数类型指的是 参数的类型 例如 一个String类型的参数和一个int类型的参数 getConstructors(String.class, int.class) 这表示的是该类中有一个参数是String和int类型的构造器,通过反射调用该构造器为:getConstructors(String.class, int.class). newInstance(”a“, 0) ,newInstance()方法中的值代表传参的值。

举例应用

public class ReflectDemo {

    public static void main(String[] args) {
        // 获取该类的Class
        Class clazz = Reflect.class;
        try {
            // 获取该类的实例
            Object object = clazz.getConstructor(String.class, int.class).newInstance("reflect", 23);
            // 通过方法名获取指定的方法
            Method method = clazz.getMethod("getName");
            // 调用该实例的该方法
            Object name = method.invoke(object);
            System.out.println(name);
            // 通过属性名获取指定的属性
            Field field = clazz.getDeclaredField("age");
            // 因为该属性是使用private修饰符修饰,所以需要设置该属性可访问,否则程序会报错
            field.setAccessible(true);
            // 调用该实例的该属性
            Object age = field.get(object);
            System.out.println(age);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

class Reflect {

    private String name;

    private int age;

    public Reflect() { }

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

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

}

补充说明:setAccessible()这个方法是为了解决通过反射访问实例中的使用private修饰符进行修饰的属性,方法或者构造器,只要在获取属性,方法或者构造器之后,调用他们之前,调用setAccessible(true)方法即可正常访问。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值