目录
一、概念
二、Class 类
三、获取类信息
四、动态调用
首页 Java java教程 Java反射是什么?Java反射机制的详细介绍

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

Sep 19, 2018 pm 02:30 PM
java反射

本篇文章给大家带来的内容是关于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<Integer> aClass1 = Integer.class;
        // 3、包装类.TYPE —— 返回基本类型的 Class 引用,基本类型在虚拟机运行时就已经加载了它的Class
        Class<Integer> aClass2 = Integer.TYPE;
        // 4、对象名.getClass()
        String str = "Hello, World";
        Class<? extends String> 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 的反射机制,我新建了一对父子类,其中涵盖了四种封装属性,以尽可能的测试多种类信息的获取:

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() 返回该类或接口的所有方法(不含继承的方法)。

public class TestMethod {
    public static void main(String[] args) {
        Class<Car> 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<Car> 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<Car> carClass = Car.class;
        Constructor<?>[] constructors = carClass.getConstructors();
        Constructor<?>[] declaredConstructors = carClass.getDeclaredConstructors();
        Constructor<Car> 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<Car> carClass = Car.class;
        // 1、实例化对象
        // 调用 Class 类的newInstance();要求对应类必须有无参构造函数,相当于 Car car = new Car()
        Car car = carClass.newInstance();
        // 调用构造器的newInstance(Object ... initargs);
        Constructor<Car> 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反射机制的详细介绍的详细内容。更多信息请关注PHP中文网其他相关文章!

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

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
威尔R.E.P.O.有交叉游戏吗?
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

使用Java反射进行逆向工程:揭秘软件的内部运作方式 使用Java反射进行逆向工程:揭秘软件的内部运作方式 Feb 19, 2024 pm 11:20 PM

Java反射是一个强大的工具,它可以让你访问类的私有字段和方法,从而揭秘软件的内部运作方式。这在逆向工程、软件分析和调试等领域非常有用。要使用Java反射,首先需要导入java.lang.reflect包。然后,你可以使用Class.forName()方法来获取一个类的Class对象。一旦有了Class对象,你就可以使用各种方法来访问类的字段和方法。例如,你可以使用getDeclaredFields()方法来获取类的所有字段,包括私有字段。你也可以使用getDeclaredMethods()方法

java反射如何获取属性的值 java反射如何获取属性的值 Jan 03, 2024 pm 03:05 PM

获取方法:1、创建一个示例对象;2、通过field.get(person)获取了字段的值,其中person是示例对象,而field是Field对象,表示一个字段;3、通过setAccessible(true)设置字段为可访问状态,即使是私有字段也可以获取其值;4、遍历字段数组,可以获取每个字段的名称和对应的值,并打印出来即可。

java的反射机制原理是什么 java的反射机制原理是什么 Jun 21, 2023 am 10:53 AM

Java反射机制原理是,当一个字节码文件加载到内存的时候,jvm会对该字节码进行解剖,创建一个对象的Class对象,jvm把字节码文件信息都存储到Class对象中,只要获取到Class对象,就能使用该对象设置对象的属性或方法等。反射机制是,在运行状态中对任意一个类,都知道这个类的所有属性和方法,对于任意一个对象,能够调用其任意属性和方法,动态获取信息以及动态调用对象方法的功能。

如何使用Java反射机制创建对象? 如何使用Java反射机制创建对象? Apr 15, 2024 pm 04:18 PM

通过Java反射机制创建对象步骤如下:加载目标类:使用Class.forName()方法。获取构造函数:使用getDeclaredConstructor()方法。创建对象:使用newInstance()方法传递参数。

深入理解Java反射机制的原理与应用 深入理解Java反射机制的原理与应用 Dec 23, 2023 am 09:09 AM

深入理解Java反射机制的原理与应用一、反射机制的概念与原理反射机制是指在程序运行时动态地获取类的信息、访问和操作类的成员(属性、方法、构造方法等)的能力。通过反射机制,我们可以在程序运行时动态地创建对象、调用方法和访问属性,而不需要在编译时知道类的具体信息。反射机制的核心是java.lang.reflect包中的类和接口。其中,Class类代表一个类的字节

如何使用java反射获取对象属性和值 如何使用java反射获取对象属性和值 Jan 03, 2024 pm 02:43 PM

获取方法:1、创建一个Person类,通过反射获取了该类的Class对象;2、使用getDeclaredFields方法获取了该类的所有字段;3、通过遍历字段数组,设置字段为可访问状态,然后使用get方法获取字段的值,并打印字段名和值即可。

Java中的NoSuchFieldException异常在什么场景下出现? Java中的NoSuchFieldException异常在什么场景下出现? Jun 25, 2023 am 11:51 AM

Java中的NoSuchFieldException异常指的是在反射过程中试图访问不存在的字段(Field)时抛出的异常。在Java中,反射可以让我们通过代码来操纵程序中的类、方法、变量等,使得程序具有更高的灵活性和扩展性。但是,在使用反射时,如果访问的字段不存在,则会抛出NoSuchFieldException异常。NoSuchFieldException

java反射有哪些调用方法 java反射有哪些调用方法 Dec 22, 2023 pm 05:09 PM

java反射调用方法有:1、Class类;2、Constructor类;3、Method类;4、Field类;5、ClassLoader类。详细介绍:1、Class类,用于获取类的信息,包括类的名称、成员变量和方法等,可以通过Class类的"newInstance()"方法创建类的实例;2、Constructor类,用于获取构造函数的参数类型、修饰符和返回类型等信息等等。

See all articles