当前位置: 首页 > news >正文

Java基础关键_031_反射(一)

目  录

一、概述

二、获取 Class 的三种方式

1.Class.forName("完整全限定类名")

2.getClass()

3.class 属性

三、通过反射机制实例化对象

 1.newInstance()(已过时)

 2.配置文件利用反射机制实例化对象

 四、反射 Class 的 Field

1.获取 Person 的属性

2.反编译 String 类的属性

3.通过反射为对象属性赋值


一、概述

  1. 反射机制是 JDK 中的一套类库,可以帮助操作或读取字节码文件;
  2. 很多 Java 框架底层都是基于反射机制实现的;
  3. 部分核心类:
    1. java.lang.Class:实例代表某个 class 文件 或 某一类型;
    2. java.lang.reflect.Field:实例代表类中的属性或字段;
    3. java.lang.reflect.Constructor:实例代表类中的构造方法;
    4. java.lang.reflect.Method:实例代表类中的方法。

二、获取 Class 的三种方式

1.Class.forName("完整全限定类名")

  1. 全限定类名含有包名,是 lang 包下的,【 java.lang 】也不可省略;
  2. 参数是字符串类型;
  3. 若类不存在,则会报 【 java.lang.ClassNotFoundException】异常;
  4. 此方法的执行,会导致类加载。
public class ReflectTest {
    static {
        System.out.println("static block");
    }

    public static void main(String[] args) throws ClassNotFoundException {
        Class<?> aClass1 = Class.forName("reflecttest.ReflectTest");
        System.out.println(aClass1);

        Class<?> aClass2 = Class.forName("java.lang.Integer");
        System.out.println(aClass2);
    }
}


2.getClass()

  1.  该方法通过引用去调用;
  2. 某类型的字节码文件在内存中仅存储一份。
public class ReflectTest {
    public static void main(String[] args) throws ClassNotFoundException {
        Class<?> aClass1 = Class.forName("java.lang.String");
        System.out.println(aClass1);

        String str = "hello";
        Class<?> aClass2 = str.getClass();
        System.out.println(aClass2);
        System.out.println(aClass1 == aClass2);

        Class<?> aClass3 = Class.forName("reflecttest.ReflectTest");
        System.out.println(aClass3);

        ReflectTest reflectTest = new ReflectTest();
        Class<? extends ReflectTest> aClass4 = reflectTest.getClass();
        System.out.println(aClass4);
        System.out.println(aClass3 == aClass4);
    }
}


3.class 属性

        在 Java 中,任何类型(包括基本数据类型)都有 class 属性,可以通过这个属性获取 Class 实例。

public class ReflectTest {
    public static void main(String[] args) throws ClassNotFoundException {
        Class<Integer> intClass = int.class;
        Class<Integer> integerClass = Integer.class;
        System.out.println(intClass);   // int
        System.out.println(integerClass);   // java.lang.Integer
    }
}

三、通过反射机制实例化对象

        那么,获取到 Class 有什么用处呢?

        这就是通过反射机制实例化对象。

 1.newInstance()(已过时)

public class Person {
    private String name;
    private int age;

    public Person() {
        System.out.println("Person 无参构造方法");
    }

    public Person(String name, int age) {
        System.out.println("Person 有参构造方法");
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

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

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
public class ReflectTest {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        Class<?> personClass = Class.forName("reflecttest.Person");
        System.out.println(personClass);
        Person person = (Person) personClass.newInstance();
        System.out.println(person);
    }
}
  1. 以上代码通过 personClass 实例化 Person 类型对象;
  2. 原理:调用 Person 的无参构造方法实例化对象;
  3. 使用此方法实现对象实例化,必须保证该类存在无参构造方法,否则会报【java.lang.InstantiationException】异常;
  4. 从 jdk 9 开始,该方法被标注已过时。


 2.配置文件利用反射机制实例化对象

# classInfo.properties 文件
className=reflecttest.Person
public class ReflectTest {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        ResourceBundle resourceBundle = ResourceBundle.getBundle("reflecttest\\classInfo"); // 加载classInfo.properties文件
        String className = resourceBundle.getString("className");   // 获取className的值
        Class<?> aClass = Class.forName(className);
        Object o = aClass.newInstance();
        System.out.println(o);
    }
}

        那么,在想要灵活实例化其他对象时,无需修改 java 文件,只需要修改配置文件即可。例如:将实例化 Person 对象改为 实例化 Date 对象。

# classInfo.properties 文件
className=java.util.Date


 四、反射 Class 的 Field

1.获取 Person 的属性

public class Person {
    public String name;
    private int age;
    protected String sex;
    public static String country;
    public static final String job = "程序员";
}
public class ReflectTest {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        // 反射获取类信息
        Class<?> aClass = Class.forName("reflecttest.Person");

        // 获取类中的所有被 public 修饰的属性
        Field[] fields = aClass.getFields();
        for (Field field : fields) {
            System.out.print(field.getName() + "    "); // name    country    job
        }

        System.out.println();

        // 获取类中的所有属性
        Field[] declaredFields = aClass.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            // 获取属性名
            System.out.print(declaredField.getName() + "    "); // name    age    sex    country    job
        }

        System.out.println();

        for (Field declaredField : declaredFields) {
            // 获取属性类型
            System.out.print(declaredField.getType().getName() + "    "); // java.lang.String    int    java.lang.String    java.lang.String    java.lang.String
        }

        System.out.println();

        for (Field declaredField : declaredFields) {
            // 获取属性类型简单名称
            System.out.print(declaredField.getType().getSimpleName() + "    "); // String    int    String    String    String
        }

        System.out.println();

        for (Field declaredField : declaredFields) {
            // 获取属性的修饰符
            System.out.print(declaredField.getModifiers() + "    ");    // 1    2    4    9    25
        }

        System.out.println();

        for (Field declaredField : declaredFields) {
            // 获取属性的修饰符名称
            System.out.print(Modifier.toString(declaredField.getModifiers()) + "    ");    // public    private    protected    public static    public static final
        }
    }
}


2.反编译 String 类的属性

public class ReflectTest {
    public static void main(String[] args) {
        String str = new String();

        // 获取类信息
        Class<? extends String> aClass = str.getClass();

        // 获取类修饰符
        String classMod = Modifier.toString(aClass.getModifiers());

        // 获取简单类名
        String className = aClass.getSimpleName();

        // 获取简单父类名
        String classSupName = aClass.getSuperclass().getSimpleName();

        // 获取父类接口
        Class<?>[] classInterfaces = aClass.getInterfaces();

        // 获取所有属性
        Field[] declaredFields = aClass.getDeclaredFields();

        // 字符串拼接
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(classMod);
        stringBuilder.append(" class ");
        stringBuilder.append(className);
        stringBuilder.append(" extends ");
        stringBuilder.append(classSupName);
        if (classInterfaces.length > 0) {
            stringBuilder.append(" implements ");
            for (int i = 0; i < classInterfaces.length; i++) {
                stringBuilder.append(classInterfaces[i].getSimpleName());
                if (i != classInterfaces.length - 1) {
                    stringBuilder.append(", ");
                }
            }
        }
        stringBuilder.append(" {\n");

        for (Field declaredField : declaredFields) {
            stringBuilder.append("\t");
            // 获取属性修饰符
            stringBuilder.append(Modifier.toString(declaredField.getModifiers()));
            stringBuilder.append(" ");
            // 获取属性类型
            stringBuilder.append(declaredField.getType().getSimpleName());
            stringBuilder.append(" ");
            // 获取属性名
            stringBuilder.append(declaredField.getName());
            stringBuilder.append(";\n");
        }
        stringBuilder.append("}");

        System.out.println(stringBuilder);
    }
}


3.通过反射为对象属性赋值

  1. 三要素:对象、属性、值。缺一不可;
  2. 若属性不是 public 的,运行会报【java.lang.IllegalAccessException】异常,需要通过 setAccessible(true) 打破封装;
public class Person {
    public String name;
    private int age;
    protected String sex;
    public static String country;
    public static final String job = "程序员";
}
public class FieldTest {
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {

        Person person = new Person();

        // 获取Person类
        Class<? extends Person> aClass = person.getClass();

        // 获取属性
        Field name = aClass.getDeclaredField("name");
        Field age = aClass.getDeclaredField("age");
        Field sex = aClass.getDeclaredField("sex");
        Field country = aClass.getDeclaredField("country");
        Field job = aClass.getDeclaredField("job");

        // 设置属性可访问
        age.setAccessible(true);
        sex.setAccessible(true);

        // 设置属性值
        name.set(person, "小明");
        age.set(person, 23);
        sex.set(person, "男");
        country.set(person, "中国");

        // 获取属性值
        System.out.println("姓名:" + name.get(person));
        System.out.println("年龄:" + age.get(person));
        System.out.println("性别:" + sex.get(person));
        System.out.println("国籍:" + country.get(person));
        System.out.println("职业:" + job.get(person));
    }
}

相关文章:

  • WebRTC C++开发入门
  • 2007-2019年各省地方财政教育支出数据
  • AI 对话艺术:Prompt 设计技巧与案例解析
  • DriveDreamer动力学模块和博弈论优化器
  • 蓝桥杯备考:BFS之马的遍历
  • <AI>dify本地部署
  • 基于音频驱动的CATIA动态曲面生成技术解析
  • 【服务器操作指南 - GPU 使用与文件传输】轻松掌握 GPU 状态查看和服务器文件传输技巧
  • NVIDIA「官方外挂」发布!RTX 5060没发售就淘汰了
  • Github Webhook 以及主动式
  • 《Java编程思想》读书笔记:第八章 多态
  • 运维规则之总结(Summary of Operation and Maintenance Rules)
  • 感觉自己的理解能力差,如何提升呢?
  • 单端信号差分信号
  • DeepSeek V3-0324 发布:编程能力再攀高峰,挑战 Claude 3.7 Sonnet
  • CSS学习笔记6——网页布局
  • Agent AI综述
  • 第八章:LLM 推理的硬件加速与部署实践
  • 医疗智能体通信整合-大模型训练中沟通优化策略研究
  • 对称加密算法和非对称加密算法
  • 黄仁勋:新一代计算平台GB300三季度上市,AI计算能力每十年提升100万倍
  • 北方今年首场高温过程开启,西北华北黄淮多地最高或达40℃
  • 上海百年龙华码头开启新航线,弥补浦江游览南段空缺
  • 大学2025丨北大教授陈平原:当卷不过AI时,何处是归途
  • 雅典卫城上空现“巨鞋”形状无人机群,希腊下令彻查
  • 流失79载,国宝文物“子弹库帛书”(二、三卷)回归祖国