【Java】反射 Reflection

本文探讨Java反射如何实现在运行时动态获取和操作类信息,包括Class、Field、Constructor和Method,以及它与内存区域的关系。通过实例展示如何使用反射创建对象、调用方法,以及其在数据库操作、XML解析和动态代理中的应用。同时,讨论反射的性能成本和典型使用案例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

反射 Reflection

本文参考文章:

  1. Java内存区域划分
  2. java 堆栈,方法区(永久代)的理解

引入

动态编程语言:程序运行时,允许改变程序结构或变量类型

从这个概念来看,Java不属于动态编程语言之类

Java的一个突出的动态相关机制:Reflection

反射概念

运行状态中

  1. 对于任意一个类,都能知道其所有属性和方法
  2. 对于任意一个对象,都能够调用其任意一个方法

Java反射功能

类 对象 动态代理

  1. 在运行时判断任意一个对象所属的类
  2. 在运行时构造任意一个类的对象
  3. 在运行时判断任意一个类所具有的成员变量和方法
  4. 在运行时调用任意一个对象的方法
  5. 生成动态代理

Java反射机制的原理

Java内存区域划分
(下方表格中未全部列出)

堆区栈区方法区(静态区)
存放类的对象。JVM将所有对象的实例的内存都分配在堆上,在堆中分配内存时间较长存取速度快,栈中存放的都是快速执行的任务,如基本数据类型的数据对象的引用存放静态变量(static变量)静态方法常量成员方法

jvm装载某类型时,装载器会定位相应的class文件,然后将其读入到虚拟机中,并提取class中的类型信息,信息存储到方法区中

Java反射机制中涉及的类

Class

类的实例表示正在运行的Java应用程序中的类和接口

Field

提供有关类或接口的属性信息,以及对其的动态访问权限

Constructor

提供关于类的单个构造方法的信息以及对其的访问权限

Method

提供关于类或接口上单独某个方法的信息

特殊:Class类

Class的实例用以表达Java程序运行时的类和接口

获取Class对象

  1. Object.getClass()
  2. Class.getSuperClass()
  3. Class.forName()
  4. 包装器类型:类名.TYPE属性

反射机制应用

  1. 操作数据库:动态创建SQL语句
  2. 解析XML:解析XML动态生成对象
  3. 动态代理
  4. 在框架中的应用:Struts、Spring、Hibernate

缺点

对性能的影响:使用反射基本上是一种解释操作,这种操作总是慢于直接执行相同的操作

代码示例

Person.class

public class Person {
    private String name;
    private Integer age;
    private List<String> hobbies;

    public Person() {

    }

    public Person(String name, Integer age, List<String> hobbies) {
        this.name = name;
        this.age = age;
        this.hobbies = hobbies;
    }

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public List<String> getHobbies() {
        return hobbies;
    }

    public void setHobbies(List<String> hobbies) {
        this.hobbies = hobbies;
    }
}

Student

public class Student extends Person implements Serializable{
    private String schoolName;
    private String stuNo;

    public Student(){

    }

    public Student(String schoolName, String stuNo) {
        this.schoolName = schoolName;
        this.stuNo = stuNo;
    }

    public String getSchoolName() {
        return schoolName;
    }

    public void setSchoolName(String schoolName) {
        this.schoolName = schoolName;
    }

    public String getStuNo() {
        return stuNo;
    }

    public void setStuNo(String stuNo) {
        this.stuNo = stuNo;
    }
}

Test.Class

public class Test {
    /**
     * 反射测试
     * @param args
     */
    public static void main(String[] args) throws ClassNotFoundException {
        Student student = new Student();
        Class<? extends Student> stuClass = student.getClass();
        System.out.println("获取student的Class");
        System.out.println("student的Class:"+stuClass+"\n");
        System.out.println("stuClass的构造方法" + Arrays.toString(stuClass.getConstructors()));

        Class<?> superclass = stuClass.getSuperclass();
        Class<?>[] interfaces = stuClass.getInterfaces();
        System.out.println("继承的类:"+superclass);
        System.out.println("实现的接口:" + Arrays.toString(interfaces));
        System.out.println();
        // 获取Student中声明的方法
        Method[] declaredMethods = stuClass.getDeclaredMethods();
        System.out.println("Student对象声明的可用方法:");
        for (Method method:declaredMethods){
            System.out.print(" 方法名称:" + method.getName());
            System.out.print("  方法参数:" + Arrays.toString(method.getParameterTypes()));
            System.out.println("  方法返回类型:" + method.getReturnType());
        }
        // 获取Student可用的所有方法
        Method[] methods = stuClass.getMethods();
        System.out.println("Student对象所有可用方法:");
        for (Method method:methods){
            System.out.print(" 方法名称:" + method.getName());
            System.out.print("  方法参数:" + Arrays.toString(method.getParameterTypes()));
            System.out.println("  方法返回类型:" + method.getReturnType());
        }
    }
}

执行结果

获取student的Class
student的Class:class com.reflect.entity.Student

stuClass的构造方法[public com.reflect.entity.Student(), public com.reflect.entity.Student(java.lang.String,java.lang.String)]
继承的类:class com.reflect.entity.Person
实现的接口:[interface java.io.Serializable]

Student对象声明的可用方法:
 方法名称:setStuNo  方法参数:[class java.lang.String]  方法返回类型:void
 方法名称:setSchoolName  方法参数:[class java.lang.String]  方法返回类型:void
 方法名称:getSchoolName  方法参数:[]  方法返回类型:class java.lang.String
 方法名称:getStuNo  方法参数:[]  方法返回类型:class java.lang.String
Student对象所有可用方法:
 方法名称:setStuNo  方法参数:[class java.lang.String]  方法返回类型:void
 方法名称:setSchoolName  方法参数:[class java.lang.String]  方法返回类型:void
 方法名称:getSchoolName  方法参数:[]  方法返回类型:class java.lang.String
 方法名称:getStuNo  方法参数:[]  方法返回类型:class java.lang.String
 方法名称:getName  方法参数:[]  方法返回类型:class java.lang.String
 方法名称:setName  方法参数:[class java.lang.String]  方法返回类型:void
 方法名称:setAge  方法参数:[class java.lang.Integer]  方法返回类型:void
 方法名称:getHobbies  方法参数:[]  方法返回类型:interface java.util.List
 方法名称:setHobbies  方法参数:[interface java.util.List]  方法返回类型:void
 方法名称:getAge  方法参数:[]  方法返回类型:class java.lang.Integer
 方法名称:wait  方法参数:[]  方法返回类型:void
 方法名称:wait  方法参数:[long, int]  方法返回类型:void
 方法名称:wait  方法参数:[long]  方法返回类型:void
 方法名称:equals  方法参数:[class java.lang.Object]  方法返回类型:boolean
 方法名称:toString  方法参数:[]  方法返回类型:class java.lang.String
 方法名称:hashCode  方法参数:[]  方法返回类型:int
 方法名称:getClass  方法参数:[]  方法返回类型:class java.lang.Class
 方法名称:notify  方法参数:[]  方法返回类型:void
 方法名称:notifyAll  方法参数:[]  方法返回类型:void
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值