java反射 -- 学习记录

一、基础知识

1.1、概念

java 反射(Reflection)是 Java 提供的一种强大的机制,允许程序在运行时动态地获取类的信息(如类名、方法、字段、构造函数等),并操作类的属性、调用类的方法。反射机制广泛应用于框架开发(如 Spring、Hibernate)和动态代理等场景。

1.2、 核心类

Java 反射的核心类位于 java.lang.reflect包中,主要包括以下类:

  • Class:表示一个类或接口,是反射的核心类。
  • Field:表示类的字段(成员变量)。
  • Method:表示类的方法。
  • Constructor:表示类的构造函数。
  • Modifier:提供对类和成员访问修饰符的解码功能。
  • Annotation:表示注解类型。
  • Parameter:表示方法或构造器的参数。

1.3、主要功能

反射的主要功能包括:

  • 获取类的信息:如类名、父类、接口、修饰符等。
  • 获取类的成员:如字段、方法、构造函数等。
  • 操作类的属性:获取或设置字段的值。
  • 调用类的方法:动态调用类的方法。
  • 创建对象:通过构造函数动态创建对象。

二、 常用方法

2.1、Class 类

2.1.1、详解

方法名 功能
forName(String className) 根据类的全限定名加载类并返回对应的 Class 对象
getName() 获取类的全限定名
getSimpleName() 获取类的简单名称(不包括包名)
getSuperclass() 获取该类的父类,返回 Class<?> 对象
getInterfaces() 获取该类实现的所有接口,返回 Class<?>[] 数组
isInterface() 判断该类是否是一个接口
isAnnotation() 判断该类是否是一个注解
isEnum() 判断该类是否是一个枚举
isPrimitive() 判断某个字段或方法的参数是否为基本数据类型
isAssignableFrom(Class<?> cls) 判断当前类是否是 cls 的父类或接口
getMethods() 获取该类的所有公共方法(包括从父类继承的),返回 Method[] 数组
getDeclaredMethods() 获取该类中声明的所有方法(不包括继承的方法),返回 Method[] 数组
getFields() 获取该类的所有公共字段(包括从父类继承的),返回 Field[] 数组
getDeclaredFields() 获取该类中声明的所有字段(不包括继承的字段),返回 Field[] 数组
getConstructors() 获取该类的所有公共构造器,返回 Constructor<?>[] 数组
getDeclaredConstructors() 获取该类中声明的所有构造器(包括私有构造器),返回 Constructor<?>[] 数组
newInstance() 创建该类的一个新实例(已过时,推荐使用 Constructor.newInstance()
isInstance(Object obj) 判断指定对象是否是该类的实例
isAnnotationPresent(Class<? extends Annotation> annotationClass) 判断该类是否被指定注解标注
getAnnotations() 获取该类上的所有注解,返回 Annotation[] 数组
getAnnotation(Class<T> annotationClass) 获取该类上的指定注解

2.1.2、举例

  • 代码
import java.lang.annotation.*;
import java.lang.reflect.*;
import java.util.Arrays;

public class TestUtil {
   

    // 自定义注解
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    public @interface MyAnnotation {
   
        String value() default "default_value";
    }

    // 示例类
    @MyAnnotation(value = "测试的注解")
    public static class MyClass implements MyInterface {
   
        private String name;
        protected int age;

        public MyClass() {
   }

        public MyClass(String name, int age) {
   
            this.name = name;
            this.age = age;
        }

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

        public String getName() {
   
            return name;
        }

        @Override
        public void doSomething() {
   
            System.out.println("Test...");
        }
    }

    public interface MyInterface {
   
        void doSomething();
    }

    public static void main(String[] args) throws Exception {
   
        // 获取 Class 对象
        Class<?> clazz = MyClass.class;

        // 获取类的基本信息
        System.out.println("全类名: " + clazz.getName());
        System.out.println("类名: " + clazz.getSimpleName());
        System.out.println("是不是接口: " + clazz.isInterface());
        System.out.println("是不是注解: " + clazz.isAnnotation());
        System.out.println("是不是枚举: " + clazz.isEnum());

        // 获取父类和实现的接口
        System.out.println("父类: " + clazz.getSuperclass().getName());
        System.out.println("实现的接口: " + Arrays.toString(clazz.getInterfaces()));

        // 获取注解
        if (clazz.isAnnotationPresent(MyAnnotation.class)) {
   
            MyAnnotation annotation = clazz.getAnnotation(MyAnnotation.class);
            System.out.println("注解 value值: " + annotation.value());
        }

        // 获取所有公共方法
        System.out.println("\n获取所有公共方法:");
        for (Method method : clazz.getMethods()) {
   
            System.out.println(method);
        }

        // 获取所有声明的方法(包括私有方法)
        System.out.println("\n获取所有声明的方法(包括私有方法):");
        for (Method method : clazz.getDeclaredMethods()) {
   
            System.out.println(method);
        }

        // 获取所有公共字段
        System.out.println("\n获取所有公共字段:");
        for (Field field : clazz.getFields()) {
   
            System.out.println(field);
        }

        // 获取所有声明的字段(包括私有字段)
        System.out.println("\n获取所有声明的字段(包括私有字段):");
        for (Field field : clazz.getDeclaredFields()) {
   
            System.out.println(field);
        }

        // 获取所有公共构造器
        System.out.println("\n获取所有公共构造器:");
        for (Constructor<?> constructor : clazz.getConstructors()) {
   
            System.out.println(constructor);
        }

        // 获取所有声明的构造器(包括私有构造器)
        System.out.println("\n获取所有声明的构造器(包括私有构造器):");
        for (Constructor<?> constructor : clazz.getDeclaredConstructors()) {
   
            System.out.println(constructor);
        }

        // 创建新实例
        Constructor<?> constructor = clazz.getDeclaredConstructor(String.class, int.class);
        Object instance = constructor.newInstance("Alice", 25);

        // 调用方法
        Method setNameMethod = clazz.getMethod("setName", String.class);
        setNameMethod.invoke(instance, "Bob");

        Method getNameMethod = clazz.getMethod("getName");
        String name = (String) getNameMethod.invoke(instance);
        System.out.println("\n调用方法修改后的Name值: " + name);

        // 访问并修改字段
        Field nameField = clazz.getDeclaredField("name");
        nameField.setAccessible(true); // 设置私有字段可访问
        nameField.set(instance, "Charlie");
        System.out.println("修改后的name值: " + nameField.get(instance));
    }
}

  • 结果
    在这里插入图片描述
    在这里插入图片描述

2.2、Field 类

2.2.1、详解

方法名 作用
getName() 获取字段名称
getType() 获取字段类型,返回 Class<?>
setAccessible(boolean flag) 设置是否允许访问私有字段
get(Object obj) 获取指定对象中的字段值
set(Object obj, Object value) 设置指定对象中的字段值
isAnnotationPresent(Class<? extends Annotation> annotationClass) 判断该字段是否被指定注解标注
getAnnotations() 获取该字段上的所有注解,返回 Annotation[] 数组
getAnnotation(Class<T> annotationClass) 获取该字段上的指定注解
getGenericType() 获取字段的泛型类型,返回 Type 对象
getModifiers() 获取字段的修饰符,返回整数值(可以通过 Modifier 类解析)
getBoolean(Object obj) 获取指定对象上的布尔类型字段值
setBoolean(Object obj, boolean value) 设置指定对象上的布尔类型字段值
getByte(Object obj) 获取指定对象上的字节类型字段值
setByte(Object obj, byte value) 设置指定对象上的字节类型字段值
getChar(Object obj) 获取指定对象上的字符类型字段值
setChar(Object obj, char value) 设置指定对象上的字符类型字段值
getShort(Object obj) 获取指定对象上的短整型字段值
setShort(Object obj, short value) 设置指定对象上的短整型字段值
getInt(Object obj) 获取指定对象上的整型字段值
setInt(Object obj, int value) 设置指定对象上的整型字段值
getLong(Object obj) 获取指定对象上的长整型字段值
setLong(Object obj, long value) 设置指定对象上的长整型字段值
getFloat(Object obj) 获取指定对象上的浮点型字段值
setFloat(Object obj, float value) 设置指定对象上的浮点型字段值
getDouble(Object obj) 获取指定对象上的双精度浮点型字段值
setDouble(Object obj, double value) 设置指定对象上的双精度浮点型字段值

2.2.2、举例

  • 代码
import java.lang.annotation.*;
import java.lang.reflect.*;

public class TestUtil {
   

    // 自定义注解
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.FIELD)
    public @interface MyFieldAnnotation {
   
        String value() default "default_value";

        int priority() default 1;
    }

    // 示例类
    public static class Person {
   
        @MyFieldAnnotation(value = "名称", priority = 3)
        private String name;

        @MyFieldAnnotation(value = "年龄", priority = 2)
        protected int age;

        public double money;

        public Person(String name, int age, double money) {
   
            this.name = name;
            this.age = age;
            this.money = money;
        }

        @Override
        public 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值