0

0

Java反射是什么?Java反射机制的详细介绍

不言

不言

发布时间:2018-09-19 14:30:16

|

2264人浏览过

|

来源于php中文网

原创

本篇文章给大家带来的内容是关于java反射是什么?java反射机制的详细介绍,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

一、概念

    Java 反射(Reflection)就是 Java 程序在运行时可以加载一个才知道类名的类,获得类的完整构造方法,并实例化出对象,给对象属性设定值或者调用对象的方法。这种在运行时动态获取类的信息以及动态调用对象的方法的功能称为 Java 的反射机制。

二、Class 类

Class 类继承自 Object 类,是 Java 反射机制的入口,封装了一个类或接口的运行时信息,通过调用 Class 类的方法可以获取到这些信息。怎么理解这个 Class 类呢?如果说普通类是所有对象方法、属性的集合,那就可以把这个 Class 类理解成是所有普通类的集合。

下面列举了获取 Class 类的几种方法:

public class TestClass {
    public static void main(String[] args) throws ClassNotFoundException {
        // 1、 Class.forName();
        Class aClass0 = Class.forName("java.lang.Object");
        // 2、类名.Class
        Class aClass1 = Integer.class;
        // 3、包装类.TYPE —— 返回基本类型的 Class 引用,基本类型在虚拟机运行时就已经加载了它的Class
        Class aClass2 = Integer.TYPE;
        // 4、对象名.getClass()
        String str = "Hello, World";
        Class aClass3 = str.getClass();
        // 5、Class类.getSuperClass() —— 获得父类的 Class 对象
        Class aClass4 = aClass3.getSuperclass();

        System.out.println(aClass0.getName());
        System.out.println(aClass1.getName());
        System.out.println(aClass2.getName());
        System.out.println(aClass3.getName());
        System.out.println(aClass4.getName());
    }
}

三、获取类信息

为了测试 Java 的反射机制,我新建了一对父子类,其中涵盖了四种封装属性,以尽可能的测试多种类信息的获取:

立即学习Java免费学习笔记(深入)”;

Vehicle.java

vpublic class Vehicle {
    private String color;
    protected Integer seat;
    int year;
    public Date createdOn;
    private String getColor() {
        return color;
    }
    protected Integer getSeat() {
        return seat;
    }
    int getYear() {
        return year;
    }
    public Date getCreatedOn() {
        return createdOn;
    }
}

Car.java

public class Car extends Vehicle {
    private String brand;
    protected Integer a;
    int b;
    public Date updatedOn;
    public Car(){}
    private Car(String brand, Integer a, int b, Date updatedOn) {
        this.brand = brand;
        this.a = a;
        this.b = b;
        this.updatedOn = updatedOn;
    }
    private String getBrand() {
        return brand;
    }
    protected Integer getA() {
        return a;
    }
    int getB() {
        return b;
    }
    public Date getUpdatedOn() {
        return updatedOn;
    }
}

1、获取方法

Class 类对方法的获取主要通过以下两种方式:

Method[] getMethods() 返回该类或接口的所有可访问公共方法(含继承的公共方法)。

Method[] getDeclaredMethods() 返回该类或接口的所有方法(不含继承的方法)。

百度文心一格
百度文心一格

百度推出的AI绘画作图工具

下载
public class TestMethod {
    public static void main(String[] args) {
        Class carClass = Car.class;
        Method[] methods = carClass.getMethods();
        Method[] declaredMethods = carClass.getDeclaredMethods();

        for (Method method : methods) {
        //for (Method method : declaredMethods) {
            System.out.println("方法名:" + method.getName());
            System.out.println("该方法所在的类或接口:" + method.getDeclaringClass());
            System.out.println("该方法的参数列表:" + method.getParameterTypes());
            System.out.println("该方法的异常列表:" + method.getExceptionTypes());
            System.out.println("该方法的返回值类型:" + method.getReturnType());
        }
    }
}

2、获取属性

Class 类对属性的获取主要通过以下两种方式:

Field[] getFields() :存放该类或接口的所有可访问公共属性(含继承的公共属性)。

Field[] getDeclaredFields():存放该类或接口的所有属性(不含继承的属性)。

public class TestField {
    public static void main(String[] args) {
        Class carClass = Car.class;
        Field[] fields = carClass.getFields();
        Field[] declaredFields = carClass.getDeclaredFields();
        //for (Field field : fields) {
        for (Field field : declaredFields) {
            System.out.println("属性名称是:" + field.getName());
            System.out.println("该属性所在的类或接口是:" + field.getDeclaringClass());
            System.out.println("该属性的类型是:" + field.getType());
            // field.getModifiers() 以整数形式返回由此 Field 对象表示的属性的 Java 访问权限修饰符
            System.out.println("该属性的修饰符是:" + Modifier.toString(field.getModifiers()));
        }
    }
}

3、获取构造函数

Class 类对构造方法的获取主要通过以下两种方式:

Constructor>[] getConstructors() :返回该类或接口的所有的公共构造方法

Constructor>[] getDeclaredConstructors():返回该类或接口的所有构造方法

public class TestConstructor {
    public static void main(String[] args) throws NoSuchMethodException {
        Class carClass = Car.class;
        Constructor[] constructors = carClass.getConstructors();
        Constructor[] declaredConstructors = carClass.getDeclaredConstructors();
        Constructor carConstructor = carClass.getDeclaredConstructor(String.class, Integer.class, Integer.TYPE, Date.class);
        //for (Constructor constructor : declaredConstructors) {
        for (Constructor constructor : constructors) {
            System.out.println("该构造器的名称是:" + constructor.getName());
            System.out.println("该构造器所在的类或接口是:" + constructor.getDeclaringClass());
            //返回构造方法的参数类型
            constructor.getParameterTypes();
        }
    }
}

四、动态调用

到目前为止,我们都是通过 Class 类的方法获取对应类属性、方法和构造函数的详细信息。接下来我们将通过这些信息,来动态创建对象、修改属性和动态调用方法。

public class Test {
    public static void main(String[] args) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
        Class carClass = Car.class;
        // 1、实例化对象
        // 调用 Class 类的newInstance();要求对应类必须有无参构造函数,相当于 Car car = new Car()
        Car car = carClass.newInstance();
        // 调用构造器的newInstance(Object ... initargs);
        Constructor declaredConstructor = carClass.getDeclaredConstructor(String.class, Integer.class, Integer.TYPE, Date.class);
        // 取消访问权限控制,即使是 private 权限也可以访问
        declaredConstructor.setAccessible(true);
        Car car1 = declaredConstructor.newInstance("brand", 21, 21, new Date());
        System.out.println(car1.getUpdatedOn());

        // 2、修改属性
        Field brand = carClass.getDeclaredField("brand");
        brand.setAccessible(true);
        System.out.println("取消访问权限控制后的值:" + brand.get(car1));
        brand.set(car1, "dnarb");
        System.out.println("修改属性后的值是:" + brand.get(car1));

        // 3、调用方法
        Method getBrand = carClass.getDeclaredMethod("getBrand");
        getBrand.setAccessible(true);
        System.out.println("调用反射方法得到的值是:" + getBrand.invoke(car1));
    }
}

相关文章

java速学教程(入门到精通)
java速学教程(入门到精通)

java怎么学习?java怎么入门?java在哪学?java怎么学才快?不用担心,这里为大家提供了java速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

831

2023.06.15

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

737

2023.07.05

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

733

2023.07.31

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

397

2023.08.01

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

398

2023.08.02

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

446

2023.08.02

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

430

2023.08.02

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

16925

2023.08.03

Java 项目构建与依赖管理(Maven / Gradle)
Java 项目构建与依赖管理(Maven / Gradle)

本专题系统讲解 Java 项目构建与依赖管理的完整体系,重点覆盖 Maven 与 Gradle 的核心概念、项目生命周期、依赖冲突解决、多模块项目管理、构建加速与版本发布规范。通过真实项目结构示例,帮助学习者掌握 从零搭建、维护到发布 Java 工程的标准化流程,提升在实际团队开发中的工程能力与协作效率。

10

2026.01.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号