利用反射技术提升Java应用的灵活性和可扩展性

简介: 利用反射技术提升Java应用的灵活性和可扩展性

前言


反射:将类的各个组成部分封装为其他对象,这就是反射机制。

好处:

  1. 可以在程序运行过程中,操作这些对象。
  2. 可以解耦,提高程序的可扩展性。





获取Class对象的方式


  1. Class.forName("全类名"):将字节码文件加载进内存,返回Class对象

多用于配置文件,将类名定义在配置文件中。读取文件,加载类

  1. 类名.class:通过类名的属性class获取

多用于参数的传递


  1. 对象.getClass():getClass()方法在Object类中定义着。

多用于对象的获取字节码的方式


结论:**同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次,不论通过哪一种方式获取的Class对象都是同一个**。


示例:

public class Person {
    private String name;
    private int age;
    private static String city="上海";
    public String a;
    protected String b;
    String c;
    private String d;
    public Person() {
    }
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public void eat(){
        System.out.println("吃饭。。。。");
    }
    public void sleep(){
        System.out.println("睡觉。。。。");
    }
}
public class Reflectyby6Demo1 {
    public static void main(String[] args) {
        /*
        1. Class.forName("全类名"):将字节码文件加载进内存,返回Class对象
        - 多用于配置文件,将类名定义在配置文件中。读取文件,加载类
        2. 类名.class:通过类名的属性class获取
        - 多用于参数的传递
        3. 对象.getClass():getClass()方法在Object类中定义着。
        - 多用于对象的获取字节码的方式
         */
        //1. Class.forName("全类名"):将字节码文件加载进内存,返回Class对象
        try {
            Class<?> aClass = Class.forName("com.tuling.domain.Person");
            //类名.class:通过类名的属性class获取
            Class<Person> personClass = Person.class;
            //3. 对象.getClass():getClass()方法在Object类中定义着。
            Person person = new Person();
            Class<? extends Person> aClass2 = person.getClass();
            System.out.println("aClass==personClass:"+(aClass==personClass));
            System.out.println("aClass2==personClass:"+(aClass==personClass));
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}





Class对象功能


获取成员变量

  • Field[] getFields() :获取所有public修饰的成员变量
  • Field getField(String name)   获取指定名称的 public修饰的成员变量
  • Field[] getDeclaredFields()  获取所有的成员变量,不考虑修饰符
  • Field getDeclaredField(String name)  




Field:成员变量


  1. 设置值  void set(Object obj, Object value)  
  2. 获取值 get(Object obj)
  3. 忽略访问权限修饰符的安全检查(暴力反射) setAccessible(true)

示例:

public class ReflectYby6Demo2 {
    @Test
    public void test1() throws Exception {
        /*
        - Field[] getFields() :获取所有public修饰的成员变量
        - Field getField(String name)   获取指定名称的 public修饰的成员变量
        - Field[] getDeclaredFields()  获取所有的成员变量,不考虑修饰符
        - Field getDeclaredField(String name)
         */
        Class<Person> personClass = Person.class;
        //
        Field[] fields = personClass.getFields();
        for (Field field : fields) {
            System.out.println(field);
        }
        System.out.println("-----------");
        Field[] declaredFields = personClass.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField);
        }
        /*
        1. 设置值
        - void set(Object obj, Object value)
        2. 获取值
        - get(Object obj)
        3. 忽略访问权限修饰符的安全检查
        - setAccessible(true):暴力反射
         */
        System.out.println("------------------");
        Field a = personClass.getField("a");
        Person p = new Person();
        a.set(p,"zhongguo");
        //获取值
        Object o = a.get(p);
        System.out.println("o:"+o);
        //a.setAccessible(true);
        Field name = personClass.getDeclaredField("name");
        /*
        Class com.qf.reflect.ReflectDemo2 can not access a member of class com.qf.domain.Person with modifiers "private"
         */
        System.out.println("name:"+name.get(p));
    }
}




获取构造方法

  • Constructor<?>[] getConstructors()  
  • Constructor<T> getConstructor(Class<?>... parameterTypes)  
  • Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)  
  • Constructor<?>[] getDeclaredConstructors()  




Constructor:构造方法

创建对象:T newInstance(Object... initargs)  

如果使用空参数构造方法创建对象,操作可以简化:Class对象的newInstance方法

示例:

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class ReflectDemo3 {
    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        /*
        2. 获取构造方法们
        - Constructor<?>[] getConstructors()
        - Constructor<T> getConstructor(类<?>... parameterTypes)
        - Constructor<T> getDeclaredConstructor(类<?>... parameterTypes)
        - Constructor<?>[] getDeclaredConstructors()
         */
        Class<Person> personClass = Person.class;
        //获取有参的构造方法
        Constructor<Person> constructor = personClass.getConstructor(String.class, int.class);
        System.out.println(constructor);
        //创建对象1
        Person person1 = constructor.newInstance("张三", 23);
        System.out.println(person1);
        //获取无参的构造方法
        Constructor<Person> constructor2 = personClass.getConstructor();
        System.out.println("constructor2:"+constructor2);
        //创建对象2
        Person person2 = constructor2.newInstance();
        System.out.println("person2:"+person2);
        //创建对象3
        Person person3 = personClass.newInstance();
        System.out.println("person3:"+person3);
        System.out.println("------------");
        Constructor<?>[] declaredConstructors = personClass.getDeclaredConstructors();
        for (Constructor<?> declaredConstructor : declaredConstructors) {
            System.out.println(declaredConstructor);
        }
        System.out.println("-------------");
        //构造器暴力访问
        //constructor2.setAccessible(true);
    }
}



获取成员方法

  • Method[] getMethods()  :获取类里面所有的public方法,包括父类里面的public方法
  • Method getMethod(String name, 类<?>... parameterTypes)  
  • Method[] getDeclaredMethods()  :获取类里面声明的所有的方法,不包括父类的方法
  • Method getDeclaredMethod(String name, 类<?>... parameterTypes)  




Method:方法对象

执行方法:Object invoke(Object obj, Object... args)  

获取方法名称:String getName

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Reflectyby6Demo4 {
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        /*
        获取成员方法:
        Method[] getMethods()
        Method getMethod(String name, 类<?>... parameterTypes)
        Method[] getDeclaredMethods()
        Method getDeclaredMethod(String name, 类<?>... parameterTypes)
         */
        Class<Person> personClass = Person.class;
        //获取指定名称的方法
        Method eat = personClass.getMethod("eat");
        //
        Person p = new Person();
        //执行方法
        eat.invoke(p);
        //获取指定名称,并且带参数的方法
        Method eat2 = personClass.getMethod("eat", String.class);
        //执行带参数的方法
        eat2.invoke(p,"wowo");
        System.out.println("--------------");
        //获取所有public修饰的方法
        Method[] methods = personClass.getMethods();
        for (Method method : methods) {
            System.out.println(method);
            //方法名
            System.out.println(method.getName());
        }
        System.out.println("-----------------");
        //获取类名
        String name = personClass.getName();
        System.out.println("类名:"+name);
    }
}




在程序使用(解析)注解


在程序使用(解析)注解:获取注解中定义的属性值


1获取注解定义的位置的对象  (Class,Method,Field)


2判断注解是否存在

isAnnotationPresent(Class)


3获取指定的注解

getAnnotation(Class)


4调用注解中的抽象方法获取配置的属性值

示例:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnno4 {
    int age() default 0;
}
import java.lang.reflect.Method;
public class Annotationyby6Demo3 {
    public static void main(String[] args) throws NoSuchMethodException {
        /*
        - 在程序使用(解析)注解:获取注解中定义的属性值
        1. 获取注解定义的位置的对象  (Class,Method,Field)
        - isAnnotationPresent(Class)
        1. 获取指定的注解
        - getAnnotation(Class)
        3. 调用注解中的抽象方法获取配置的属性值
         */
        Class<Person> personClass = Person.class;
        System.out.println("------------");
        Method test = personClass.getMethod("test");
        System.out.println(test.isAnnotationPresent(MyAnno4.class));
        //获取方法上定义的注解
        if(test.isAnnotationPresent(MyAnno4.class)){
            System.out.println("test方法有定义注解");
            MyAnno4 annotation2 = test.getAnnotation(MyAnno4.class);
            int age2 = annotation2.age();
            System.out.println("age2:"+age2);
        }
    }
}





最后


本期结束咱们下次再见👋~

🌊 关注我不迷路,如果本篇文章对你有所帮助,或者你有什么疑问,欢迎在评论区留言,我一般看到都会回复的。大家点赞支持一下哟~ 💗

相关文章
|
26天前
|
Java API Maven
2025 Java 零基础到实战最新技术实操全攻略与学习指南
本教程涵盖Java从零基础到实战的全流程,基于2025年最新技术栈,包括JDK 21、IntelliJ IDEA 2025.1、Spring Boot 3.x、Maven 4及Docker容器化部署,帮助开发者快速掌握现代Java开发技能。
259 1
|
1月前
|
存储 数据采集 搜索推荐
Java 大视界 -- Java 大数据在智慧文旅旅游景区游客情感分析与服务改进中的应用实践(226)
本篇文章探讨了 Java 大数据在智慧文旅景区中的创新应用,重点分析了如何通过数据采集、情感分析与可视化等技术,挖掘游客情感需求,进而优化景区服务。文章结合实际案例,展示了 Java 在数据处理与智能推荐等方面的强大能力,为文旅行业的智慧化升级提供了可行路径。
Java 大视界 -- Java 大数据在智慧文旅旅游景区游客情感分析与服务改进中的应用实践(226)
|
1月前
|
存储 监控 数据可视化
Java 大视界 -- 基于 Java 的大数据可视化在企业生产运营监控与决策支持中的应用(228)
本文探讨了基于 Java 的大数据可视化技术在企业生产运营监控与决策支持中的关键应用。面对数据爆炸、信息孤岛和实时性不足等挑战,Java 通过高效数据采集、清洗与可视化引擎,助力企业构建实时监控与智能决策系统,显著提升运营效率与竞争力。
|
1月前
|
JavaScript 安全 前端开发
Java开发:最新技术驱动的病人挂号系统实操指南与全流程操作技巧汇总
本文介绍基于Spring Boot 3.x、Vue 3等最新技术构建现代化病人挂号系统,涵盖技术选型、核心功能实现与部署方案,助力开发者快速搭建高效、安全的医疗挂号平台。
122 3
|
1月前
|
机器学习/深度学习 人工智能 自然语言处理
Java 大视界 -- Java 大数据机器学习模型在自然语言生成中的可控性研究与应用(229)
本文深入探讨Java大数据与机器学习在自然语言生成(NLG)中的可控性研究,分析当前生成模型面临的“失控”挑战,如数据噪声、标注偏差及黑盒模型信任问题,提出Java技术在数据清洗、异构框架融合与生态工具链中的关键作用。通过条件注入、强化学习与模型融合等策略,实现文本生成的精准控制,并结合网易新闻与蚂蚁集团的实战案例,展示Java在提升生成效率与合规性方面的卓越能力,为金融、法律等强监管领域提供技术参考。
|
1月前
|
存储 人工智能 算法
Java 大视界 -- Java 大数据在智能医疗影像数据压缩与传输优化中的技术应用(227)
本文探讨 Java 大数据在智能医疗影像压缩与传输中的关键技术应用,分析其如何解决医疗影像数据存储、传输与压缩三大难题,并结合实际案例展示技术落地效果。
|
1月前
|
机器学习/深度学习 安全 Java
Java 大视界 -- Java 大数据在智能金融反洗钱监测与交易异常分析中的应用(224)
本文探讨 Java 大数据在智能金融反洗钱监测与交易异常分析中的应用,介绍其在数据处理、机器学习建模、实战案例及安全隐私等方面的技术方案与挑战,展现 Java 在金融风控中的强大能力。
|
1月前
|
机器学习/深度学习 算法 Java
Java 大视界 -- Java 大数据机器学习模型在生物信息学基因功能预测中的优化与应用(223)
本文探讨了Java大数据与机器学习模型在生物信息学中基因功能预测的优化与应用。通过高效的数据处理能力和智能算法,提升基因功能预测的准确性与效率,助力医学与农业发展。
|
2月前
|
安全 算法 Java
Java 多线程:线程安全与同步控制的深度解析
本文介绍了 Java 多线程开发的关键技术,涵盖线程的创建与启动、线程安全问题及其解决方案,包括 synchronized 关键字、原子类和线程间通信机制。通过示例代码讲解了多线程编程中的常见问题与优化方法,帮助开发者提升程序性能与稳定性。
117 0

热门文章

最新文章