数据结构初阶:反射-->Java达成

这是下面实现的全部代码:javacode-25year: 2025年java代码

1.反射的概念

一个.java资料(如文档内只有一个类)经过编译生成.class材料,.class再被加载到JVM生成一个Class对象(实例)。(有多少个类就生成多少个Class对象,内部类也会生成单独的Class对象)

通过Java反射机制允许使用指定对象中的任何变量方法(任何都行,包括被private 修饰的 ),甚至修改变量方法

2.反射相关的类

类名用途
Class代表类的实体,在运行的Java应用程序中表示类和接口
Field代表类的成员变量/类的属性
Method代表类的途径
Constructor代表类的构造方法

2.1Class类中相关的方法

(后面有相关方法的使用示例)

  • 常用获得类相关的方式
方法用途
getClassLoader()获得类的加载器
getDeclaredClasses()返回一个数组,数组中包含该类中所有类和接口类的对象(包括私有的)
forName(String className)根据类名返回类的对象
newInstance()创建类的实例
getName()获得类的完整路径名字
  • 常用获得类中属性相关的方法(以下方法返回值为Field相关)

    方法

    用途

    getField(String name)

    获得某个公有的属性对象

    getFields()

    获得所有公有的属性对象

    getDeclaredField(Stringname)

    获得某个属性对象

    getDeclaredFields()

    获得所有属性对象

  • 获得类中注解相关的方法(了解)

    方法

    用途

    getAnnotation(ClassannotationClass)

    返回该类中与参数类型匹配的公有注解对象

    getAnnotations()

    返回该类所有的公有注解对象

    getDeclaredAnnotation(ClassannotationClass)

    返回该类中与参数类型匹配的所有注解对象

    getDeclaredAnnotations()

    返回该类所有的注解对象

  • 获得类中构造器(构造函数)相关的方法(以下方法返回值为Constructor相关)

    方法

    用途

    getConstructor(Class...<?> parameterTypes)

    获得该类中与参数类型匹配的公有构造方法

    getConstructors()

    获得该类的所有公有构造方法

    getDeclaredConstructor(Class...<?> parameterTypes)

    获得该类中与参数类型匹配的构造方法

    getDeclaredConstructors()

    获得该类所有构造方法

  • 获得类中方法相关的方法(以下方法返回值为Method相关

    方法

    用途

    getMethod(String name, Class...<?> parameterTypes)

    获得该类某个公有的方法

    getMethods()

    获得该类所有公有的方法

    getDeclaredMethod(String name, Class...<?> parameterTypes)

    获得该类某个手段

    getDeclaredMethods()

    获得该类所有方式

技巧:获取类对象的属性、构造方法和其他方法所使用的手段名有一个共同特征。当我们访问类对象中的公有成员时都没有加Declared,在原本获取公有成员的办法上加上Declared就可以获取某个成员,如:getMethods()——》获得该类所有公有的方法     

getDeclaredMethods()——》获得该类所有方法

3.反射示例

3.1获得Class对象的技巧有三种

在反射之前,要获得需要反射的Class类对象,然后通过Class的技巧,反射要获取的成员。

第一种,运用静态方法 Class.forName("类的全路径名");

前提:已明确类的全路径名

第二种,.class 方法。

仅适用于,编译前已确定要操作的类

第三种,使用类对象的getClass();方法

示例:

下面这个实验说明JVM只会产生一个Class对象

三种生成Class对象的方法用的最多的是第一种。

3.2使用Class对象反射Student实例

所用方法上面均有。

Student类代码:

public class Student {
    //私有属性name
    private String name = "My age is";
    //公有属性age
    public int age = 18;
    //不带参数的构造方法
    public Student() {
        System.out.println("demo1.Student()");
    }
    private Student(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("demo1.Student(String,name)");
    }
    private void eat() {
        System.out.println("i am eat");
    }
    public void sleep() {
        System.out.println("i am pig");
    }
    private void function(String str) {
        System.out.println(str);
    }
    @Override
    public String toString() {
        return "demo1.Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

3.3反射私有Constructor(构造方法)

疑惑:一切都是按照逻辑写的代码为什么会报错呢?如果没报错,这里应该打印demo1.Student{name=我, age=18},上面在选构造器时已经调用了对应构造函数的实例了(name与age被重新赋值)。

解决方法:我们可能想到private本来就是为了限制访问的,但现在好了,直接反射什么都可以拿到了...,所以为了确认你是否真要反射获取私有的成员,每次都要setAccessible(true);

这里我要解释一下,catch中的全是编译错误,但为什么我要扔出运行时异常呢,是因为catch是架构自动生成的的,大家可以改;

修改后的代码:

不反射私有成员就不需要某.setAccessible() 。

3.4反射私有Field(属性)

3.5反射私有Method(方法)

4.总结

文章只讲述了反射私有属性与方法,但公有的也类似。

反射不难,只是要用到许多方式。这也说明反射的效率不会很高,我们获取私有成员也不是那么容易的,private还是有一定的安全性。

posted @ 2025-12-21 22:28  gccbuaa  阅读(0)  评论(0)    收藏  举报