利用反射技术提升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);
        }
    }
}





最后


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

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

相关文章
|
1月前
|
人工智能 算法 Java
Java与AI驱动区块链:构建智能合约与去中心化AI应用
区块链技术和人工智能的融合正在开创去中心化智能应用的新纪元。本文深入探讨如何使用Java构建AI驱动的区块链应用,涵盖智能合约开发、去中心化AI模型训练与推理、数据隐私保护以及通证经济激励等核心主题。我们将完整展示从区块链基础集成、智能合约编写、AI模型上链到去中心化应用(DApp)开发的全流程,为构建下一代可信、透明的智能去中心化系统提供完整技术方案。
215 3
|
1月前
|
消息中间件 缓存 Java
Spring框架优化:提高Java应用的性能与适应性
以上方法均旨在综合考虑Java Spring 应该程序设计原则, 数据库交互, 编码实践和系统架构布局等多角度因素, 旨在达到高效稳定运转目标同时也易于未来扩展.
116 8
|
2月前
|
人工智能 Java API
Java与大模型集成实战:构建智能Java应用的新范式
随着大型语言模型(LLM)的API化,将其强大的自然语言处理能力集成到现有Java应用中已成为提升应用智能水平的关键路径。本文旨在为Java开发者提供一份实用的集成指南。我们将深入探讨如何使用Spring Boot 3框架,通过HTTP客户端与OpenAI GPT(或兼容API)进行高效、安全的交互。内容涵盖项目依赖配置、异步非阻塞的API调用、请求与响应的结构化处理、异常管理以及一些面向生产环境的最佳实践,并附带完整的代码示例,助您快速将AI能力融入Java生态。
425 12
|
2月前
|
安全 Java API
Java Web 在线商城项目最新技术实操指南帮助开发者高效完成商城项目开发
本项目基于Spring Boot 3.2与Vue 3构建现代化在线商城,涵盖技术选型、核心功能实现、安全控制与容器化部署,助开发者掌握最新Java Web全栈开发实践。
338 1
|
2月前
|
安全 Cloud Native Java
Java 模块化系统(JPMS)技术详解与实践指南
本文档全面介绍 Java 平台模块系统(JPMS)的核心概念、架构设计和实践应用。作为 Java 9 引入的最重要特性之一,JPMS 为 Java 应用程序提供了强大的模块化支持,解决了长期存在的 JAR 地狱问题,并改善了应用的安全性和可维护性。本文将深入探讨模块声明、模块路径、访问控制、服务绑定等核心机制,帮助开发者构建更加健壮和可维护的 Java 应用。
242 0
|
2月前
|
安全 Java API
Java SE 与 Java EE 区别解析及应用场景对比
在Java编程世界中,Java SE(Java Standard Edition)和Java EE(Java Enterprise Edition)是两个重要的平台版本,它们各自有着独特的定位和应用场景。理解它们之间的差异,对于开发者选择合适的技术栈进行项目开发至关重要。
343 1
|
2月前
|
监控 Cloud Native Java
Quarkus 云原生Java框架技术详解与实践指南
本文档全面介绍 Quarkus 框架的核心概念、架构特性和实践应用。作为新一代的云原生 Java 框架,Quarkus 旨在为 OpenJDK HotSpot 和 GraalVM 量身定制,显著提升 Java 在容器化环境中的运行效率。本文将深入探讨其响应式编程模型、原生编译能力、扩展机制以及与微服务架构的深度集成,帮助开发者构建高效、轻量的云原生应用。
319 44
|
3月前
|
Java 测试技术 API
2025 年 Java 开发者必知的最新技术实操指南全览
本指南涵盖Java 21+核心实操,详解虚拟线程、Spring Boot 3.3+GraalVM、Jakarta EE 10+MicroProfile 6微服务开发,并提供现代Java开发最佳实践,助力开发者高效构建高性能应用。
583 4
|
3月前
|
安全 Java 编译器
new出来的对象,不一定在堆上?聊聊Java虚拟机的优化技术:逃逸分析
逃逸分析是一种静态程序分析技术,用于判断对象的可见性与生命周期。它帮助即时编译器优化内存使用、降低同步开销。根据对象是否逃逸出方法或线程,分析结果分为未逃逸、方法逃逸和线程逃逸三种。基于分析结果,编译器可进行同步锁消除、标量替换和栈上分配等优化,从而提升程序性能。尽管逃逸分析计算复杂度较高,但其在热点代码中的应用为Java虚拟机带来了显著的优化效果。
119 4
|
3月前
|
设计模式 XML 安全
Java枚举(Enum)与设计模式应用
Java枚举不仅是类型安全的常量,还具备面向对象能力,可添加属性与方法,实现接口。通过枚举能优雅实现单例、策略、状态等设计模式,具备线程安全、序列化安全等特性,是编写高效、安全代码的利器。