Java反射机制(详解如何使用反射)

1.定义

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。

2.作用

在日常的开发中无外乎两种最常用的用法:

  • 操作因访问权限限制的属性和方法;

  • 实现自定义注解;

3.反射的四个核心类

  • java.lang.Class.java:类对象;

  • java.lang.reflect.Constructor.java:类的构造器对象;

  • java.lang.reflect.Method.java:类的方法对象;

  • java.lang.reflect.Field.java:类的属性对象;

4.通过反射获取类、属性、方法的基本操作,也是本文的重点

下面我将用代码方式逐步分析反射的具体用法,下文中用到的获取类、属性、构造器的相关方法不太清楚的请参考我的另一篇博客https://blog.csdn.net/Lychee__/article/details/121396023

 a.获取Class对象(使用类名.class方式)

(获取Class对象有三种方式,在这里不做具体分析,需要了解的请自行查阅喔)

        //获取Class类
        Class<Student> aClass = Student.class;
        System.out.println("获取到的类为:"+aClass.getName());//输出获取到的类

 控制台打印结果为:

b.通过获取的Class类获取目标类的对象(使用getContructor()方法)

       Constructor<Student> aClass1Constructor = aClass.getConstructor();
       Student student = aClass1Constructor.newInstance();
       System.out.println("获取到的对象为:"+student.getName());//输出获取到的对象

c.通过获取的对象获取该类的所有方法(使用getDeclareMethods()方法)

        Method[] methods = student.getClass().getDeclaredMethods();
        for (int i = 0; i < methods.length; i++) {
            System.out.println("获取到的方法有:"+methods[i].getName());
        }

for循环遍历并在控制台输出:

 c.通过反射获取类中的某个方法并调用该方法(使用getDeclaredMethod()方法)(示例setMobile)

        Method setMobile = aClass.getDeclaredMethod("setMobile", String.class);
        //通过Modifier.isXXX判断你获取的方法的权限修饰符,正确输出为true,否则为false
        System.out.println("method is public:"+ 
        Modifier.isPublic(setMobile.getModifiers()));
        //通过getParameterTypes()获取该方法的参数类型
        Class<?>[] parameterTypes = setMobile.getParameterTypes();
        for (int i = 0; i <parameterTypes.length; i++) {
            System.out.println("获取到方法的参数类型为:"+parameterTypes[i].getName());
        }
        setMobile.invoke(student,"15560695750");
        Method getMobile = aClass.getDeclaredMethod("getMobile");
        //注解测试
        FunctionValidate Validate = new FunctionValidate();
        Validate.validate(student);
        System.out.println("学生的手机号为:"+Validate.validate(student));

控制台打印结果为:

 d.反射获取所有属性(使用getDeclaredFields()方法)

        Field[] fields = aClass.getDeclaredFields();
        for (int i = 0; i < fields.length; i++) {
            System.out.println("获取到该类的属性有:"+fields[i].getName());
        }

 控制台打印结果为:

 e.获取单个属性并进行赋值操作(使用getDeclaredFields()方法、set方法)

        Field name = aClass.getDeclaredField("name");
        name.setAccessible(true);
        //Method setName = aClass.getDeclaredMethod("setName", String.class);
        name.set(aClass,"小红");

下面附上以上片段总结代码,测试请自取:

Student类Student.java

package com.lychee.annotationStudy.lengthAnnotation;

import com.lychee.annotationStudy.lengthAnnotation.Length;
import com.lychee.annotationStudy.lengthAnnotation.FunctionValidate;


public class Student {
    private int id; // 学号
    private String name; // 姓名
    @Length(min = 11, max = 11, errorMsg = "电话号码的长度必须为11位")
    private String mobile; // 手机号码(11位)

    public Student() {
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public String getMobile() {
        return mobile;
    }

    public void setMobile(String mobile) {
        this.mobile = mobile;
    }
}


测试类Test.java

package com.lychee.annotationStudy.lengthAnnotation;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class Test {
    public static void main(String[] args) throws Exception{
        //获取Class类
        Class<Student> aClass = Student.class;
        System.out.println("获取到的类为:"+aClass.getName());//输出获取到的类

        //通过获取的Class类获取目标类的对象
        Constructor<Student> aClass1Constructor = aClass.getConstructor();
        //aClass1Constructor.setAccessible(true);//反射时访问私有变
        Student student = aClass1Constructor.newInstance();
        System.out.println("获取到的对象为:"+student.getName());//输出获取到的对象

        //通过获取的对象获取类的所有方法
        Method[] methods = student.getClass().getDeclaredMethods();
        for (int i = 0; i < methods.length; i++) {
            System.out.println("获取到的方法有:"+methods[i].getName());
        }

        //通过反射获取类中的某个方法并调用该方法(示例setMobile)
        Method setMobile = aClass.getDeclaredMethod("setMobile", String.class);
        //通过Modifier.isXXX判断你获取的方法的权限修饰符,正确输出为true,否则为false
        System.out.println("method is public:"+ Modifier.isPublic(setMobile.getModifiers()));
        //通过getParameterTypes()获取该方法的参数类型
        Class<?>[] parameterTypes = setMobile.getParameterTypes();
        for (int i = 0; i <parameterTypes.length; i++) {
            System.out.println("获取到方法的参数类型为:"+parameterTypes[i].getName());
        }
        setMobile.invoke(student,"15560695750");
        Method getMobile = aClass.getDeclaredMethod("getMobile");
        System.out.println("学生的手机号为:"+student.getMobile);

        //反射获取所有属性
        Field[] fields = aClass.getDeclaredFields();
        for (int i = 0; i < fields.length; i++) {
            System.out.println("获取到该类的属性有:"+fields[i].getName());
        }
        //获取单个属性并进行赋值操作

        Field name = aClass.getDeclaredField("name");
        name.setAccessible(true);
        //Method setName = aClass.getDeclaredMethod("setName", String.class);
        name.set(aClass,"小红");

    }
}

以上就是本次Java反射具体实现的全部内容了,具体个人理解还需读者自行思考,如有指正请联系我,感谢阅读。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值