• 【Java 基础】Java 反射使用方法简介


    【Java 基础】Java 反射使用方法简介



    一、反射简介

    Java 反射机制是一个很强大的机制,它可以让使用者能在运行的时候进行类的操作

    1. 获取 Class 的方法

    1. getClass() 方法
    Class testClazz = Test.getClass()
    
    1. 类名.class
    Class testClazz = Test.class
    
    1. Class.forName() 方法
    Class testClazz = Class.forName("com.test.Test")
    

    2. Class 类常用方法解释

    方法返回类型所属类解释
    getFields()Field[]java.lang.Class获取类中所有 public 修饰的变量
    getDeclaredFields()Field[]java.lang.Class获取类中所有的变量
    getField(String)Fieldjava.lang.Class获取指定名称的变量
    getMethods()Method[]java.lang.Class获取类中所有 public 修饰的方法
    getDeclaredMethods()Method[]java.lang.Class获取类中所有的方法
    getMethod(String, Class…)Methodjava.lang.Class获取指定名称的方法, 可以填写参数类型
    getConstructors()Constructor[]java.lang.Class获取类中所有 public 修饰的构造器
    getDeclaredConstructors()Constructor[]java.lang.Class获取类中所有的构造器
    getConstructor(Class…)Constructorjava.lang.Class获取指定参数类型的构造器, 参数需要填写参数类型, 如果有多个参数, 则可以填写多个参数类型
    getAnnotations()Annotation[]java.lang.Class获取所有 public 修饰的注解
    getDeclaredAnnotations()Annotation[]java.lang.Class获取所有的注解
    getAnnotation(Class)Annotationjava.lang.Class获取指定类型的注解, 参数中需要填写注解类型
    getModifiers()intjava.lang.Class获取所有的修饰符类型, 会返回 int 类型的值, 可以使用 Modifier.toString() 进行值的解析
    getSuperclass()Classjava.lang.Class获取父类, 如果没有继承父类, 则会返回 null
    getInterfaces()Class[]java.lang.Class获取所有的接口
    newInstance()Tjava.lang.Class生成类的实例

    3. 例子

    【1】获取类中所有构造器、方法、变量

    在例子中,分别打印了构造器、方法、变量,从打印出来的结果来看,带 Declared 的方法会只会获取当前类所有修饰类型的方法或者变量,而不带 Declared 的方法则会获取类所有 public 的方法或者变量,包括继承的父类以及实现的接口中的 public 修饰的方法或者变量也会打印出来。

    一句话总结就是:如果要找当前类以及父类和接口中的 public 的内容,则使用不带 Declared 的方法,如果要查找当前类中所有修饰符修饰的内容,则使用带 Declared 的方法。

    • AbstractTest.java
    public abstract class AbstractTest {  
      
        private String abstractField;  
      
        public Double abstractDoubleField;  
      
        public AbstractTest() {  
      
        }  
      
        abstract void abstractMethod();  
      
        private void abstractPrivateMethod() {  
            System.out.println("abstractPrivateMethod");  
        }  
      
        public void abstractPublicMethod() {  
            System.out.println("abstractPublicMethod");  
        }  
    }
    
    • TestInterface.java
    public interface TestInterface {  
      
        String interfaceField = "接口变量";  
      
        default void interfaceDefaultMethod() {  
            System.out.println("interfaceMethod");  
        }  
      
        String interfacePublicMethod();  
    }
    
    • Test.java
    class Test extends AbstractTest implements TestInterface {  
      
        private String testName;  
      
        protected Double size;  
      
        public String testClass;  
      
        private Test() {  
      
        }  
      
        public Test(String testName, Double size) {  
            this.testName = testName;  
            this.size = size;  
        }  
      
        public String getTestName() {  
            return testName;  
        }  
      
        public void setTestName(String testName) {  
            this.testName = testName;  
        }  
      
        private void testMethod() {  
            System.out.println("测试方法");  
        }  
      
        public static String testPrint() {  
            System.out.println("打印测试方法");  
            return "测试";  
        }  
      
        @Override  
        void abstractMethod() {  
            System.out.println("abstractMethod");  
        }  
      
        @Override  
        public String interfacePublicMethod() {  
            System.out.println("interfacePublicMethod");  
            return "interfacePublicMethod";  
        }  
    }
    
    • ReflectionTest.java
    public class ReflectionTest {  
      
        public static void main(String[] args) {  
            ReflectionTest test = new ReflectionTest();  
      
            System.out.println("Constructors:");  
            test.printConstructors(Test.class);  
            System.out.println("======================================");  
            System.out.println("DeclaredConstructors:");  
            test.printDeclaredConstructors(Test.class);  
            System.out.println("======================================");  
            System.out.println("Fields:");  
            test.printFields(Test.class);  
            System.out.println("======================================");  
            System.out.println("DeclaredFields:");  
            test.printDeclaredFields(Test.class);  
            System.out.println("======================================");  
            System.out.println("Methods:");  
            test.printMethods(Test.class);  
            System.out.println("======================================");  
            System.out.println("DeclaredMethods:");  
            test.printDeclaredMethods(Test.class);  
        }  
      
        public void printConstructors(Class<Test> clazz) {  
            Constructor<?>[] constructors = clazz.getConstructors();  
      
            this.constructorsPrint(constructors);  
        }  
      
        public void printDeclaredConstructors(Class<Test> clazz) {  
            Constructor<?>[] constructors = clazz.getDeclaredConstructors();  
      
            this.constructorsPrint(constructors);  
        }  
      
        private void constructorsPrint(Constructor<?>[] constructors) {  
            for (Constructor<?> constructor : constructors) {  
                String constructorName = constructor.getName();  
                System.out.println("构造器名:" + constructorName + " {");  
      
                String modifiers = Modifier.toString(constructor.getModifiers());  
                System.out.print("修饰符:");  
                if (modifiers.length() > 0) {  
                    System.out.print(modifiers + ";");  
                }  
      
                Class<?>[] parameterTypes = constructor.getParameterTypes();  
                System.out.print("\n" + "参数类型:");  
                for (Class<?> parameterType : parameterTypes) {  
                    System.out.print(parameterType.getName() + "; ");  
                }  
      
                System.out.println("\n" + "}");  
            }  
        }  
      
        public void printFields(Class<Test> clazz) {  
            Field[] fields = clazz.getFields();  
      
            this.fieldPrint(fields);  
        }  
      
        public void printDeclaredFields(Class<Test> clazz) {  
            Field[] declaredFields = clazz.getDeclaredFields();  
      
            this.fieldPrint(declaredFields);  
        }  
      
        private void fieldPrint(Field[] fields) {  
            for (Field field : fields) {  
                String fieldName = field.getName();  
                Class<?> fieldType = field.getType();  
      
                System.out.println("变量名:" + fieldName + " {");  
                System.out.println("变量类型:" + fieldType);  
      
                String modifiers = Modifier.toString(field.getModifiers());  
                System.out.print("修饰符:");  
                if (modifiers.length() > 0) {  
                    System.out.print(modifiers + ";");  
                }  
      
                System.out.println("\n" + "}");  
            }  
        }  
      
        public void printMethods(Class<Test> clazz) {  
            Method[] methods = clazz.getMethods();  
      
            this.methodPrint(methods);  
        }  
      
        public void printDeclaredMethods(Class<Test> clazz) {  
            Method[] declaredMethods = clazz.getDeclaredMethods();  
      
            this.methodPrint(declaredMethods);  
        }  
      
        private void methodPrint(Method[] methods) {  
            for (Method method : methods) {  
                String methodName = method.getName();  
                Class<?> returnType = method.getReturnType();  
      
                System.out.println("方法名:" + methodName + " {");  
                System.out.println("返回类型:" + returnType);  
      
                String modifiers = Modifier.toString(method.getModifiers());  
                System.out.print("修饰符:");  
                if (modifiers.length() > 0) {  
                    System.out.print(modifiers + ";");  
                }  
      
                System.out.println("\n" + "}");  
            }  
        }  
    }
    

    【2】访问并设置 private 修饰的变量值

    如果想要对当前类中某个使用 private 修饰的变量进行访问并设置值,会出现下面的错误,来提示无法获取 private 修饰的变量的值:
    java.lang.IllegalAccessException: Class test.common.ReflectionTest can not access a member of class test.common.Test with modifiers "private"

    如果想获取 private 修饰的变量的值,则需要将 Java 的安全访问控制设置为可访问,才能对私有域进行访问。

    Class<? extends Test> clazz = test.getClass();  
    Field testName = clazz.getDeclaredField("testName");  
    testName.setAccessible(true);  
    Object testValue = testName.get(test);  
    System.out.println(testName + " 旧值:" + testValue);  
      
    testName.set(test, "新的 testName测试");  
    Object newTestValue = testName.get(test);  
    System.out.println(testName + " 新值:" + newTestValue);
    
  • 相关阅读:
    ConvNext模型复现--CVPR2022
    ultraEdit正则匹配多行(xml用)
    Scala基础【HelloWorld代码解析,变量和标识符】
    【Vue】(二)Vue组件化思想、全局组件与局部组件、父子组件、父子组件通信、slot-插槽
    【LibTorch】C++中部署PyTorch模型(以DenseTNT模型为例)
    Design patterns--策略模式
    大数据课程L1——网站流量项目的概述&&整体架构
    智能生成并盘活API研发资产
    绕圆旋转动画组件,拿过来直接用
    网络层--IP协议
  • 原文地址:https://blog.csdn.net/weixin_41645142/article/details/127126776