程序员scholar 程序员scholar
首页
  • Java 基础

    • JavaSE
    • JavaIO
    • JavaAPI速查
  • Java 高级

    • JUC
    • JVM
    • Java新特性
    • 设计模式
  • Web 开发

    • Servlet
    • Java网络编程
  • Web 标准

    • HTML
    • CSS
    • JavaScript
  • 前端框架

    • Vue2
    • Vue3
    • Vue3 + TS
    • 微信小程序
    • uni-app
  • 工具与库

    • jQuery
    • Ajax
    • Axios
    • Webpack
    • Vuex
    • WebSocket
    • 第三方登录
  • 后端与语言扩展

    • ES6
    • Typescript
    • node.js
  • Element-UI
  • Apache ECharts
  • 数据结构
  • HTTP协议
  • HTTPS协议
  • 计算机网络
  • Linux常用命令
  • Windows常用命令
  • SQL数据库

    • MySQL
    • MySQL速查
  • NoSQL数据库

    • Redis
    • ElasticSearch
  • 数据库

    • MyBatis
    • MyBatis-Plus
  • 消息中间件

    • RabbitMQ
  • 服务器

    • Nginx
  • Spring框架

    • Spring6
    • SpringMVC
    • SpringBoot
    • SpringSecurity
  • SpringCould微服务

    • SpringCloud基础
    • 微服务之DDD架构思想
  • 日常必备

    • 开发常用工具包
    • Hutoll工具包
    • IDEA常用配置
    • 开发笔记
    • 日常记录
    • 项目部署
    • 网站导航
    • 产品学习
    • 英语学习
  • 代码管理

    • Maven
    • Git教程
    • Git小乌龟教程
  • 运维工具

    • Docker
    • Jenkins
    • Kubernetes
  • 算法笔记

    • 算法思想
    • 刷题笔记
  • 面试问题常见

    • 十大经典排序算法
    • 面试常见问题集锦
关于
GitHub (opens new window)
首页
  • Java 基础

    • JavaSE
    • JavaIO
    • JavaAPI速查
  • Java 高级

    • JUC
    • JVM
    • Java新特性
    • 设计模式
  • Web 开发

    • Servlet
    • Java网络编程
  • Web 标准

    • HTML
    • CSS
    • JavaScript
  • 前端框架

    • Vue2
    • Vue3
    • Vue3 + TS
    • 微信小程序
    • uni-app
  • 工具与库

    • jQuery
    • Ajax
    • Axios
    • Webpack
    • Vuex
    • WebSocket
    • 第三方登录
  • 后端与语言扩展

    • ES6
    • Typescript
    • node.js
  • Element-UI
  • Apache ECharts
  • 数据结构
  • HTTP协议
  • HTTPS协议
  • 计算机网络
  • Linux常用命令
  • Windows常用命令
  • SQL数据库

    • MySQL
    • MySQL速查
  • NoSQL数据库

    • Redis
    • ElasticSearch
  • 数据库

    • MyBatis
    • MyBatis-Plus
  • 消息中间件

    • RabbitMQ
  • 服务器

    • Nginx
  • Spring框架

    • Spring6
    • SpringMVC
    • SpringBoot
    • SpringSecurity
  • SpringCould微服务

    • SpringCloud基础
    • 微服务之DDD架构思想
  • 日常必备

    • 开发常用工具包
    • Hutoll工具包
    • IDEA常用配置
    • 开发笔记
    • 日常记录
    • 项目部署
    • 网站导航
    • 产品学习
    • 英语学习
  • 代码管理

    • Maven
    • Git教程
    • Git小乌龟教程
  • 运维工具

    • Docker
    • Jenkins
    • Kubernetes
  • 算法笔记

    • 算法思想
    • 刷题笔记
  • 面试问题常见

    • 十大经典排序算法
    • 面试常见问题集锦
关于
GitHub (opens new window)
npm

(进入注册为作者充电)

  • Java8新特性

    • Java8新特性简介
    • Lambda 表达式
    • 函数式接口
    • 方法的引用
    • 构造器和数组的引用
    • Stream 流式编程
    • 并行流与串行流
    • Optional 类的使用
    • 对反射的支持增强
      • 1. 反射简介与应用场景
      • 2. Java 反射的性能优化
        • 性能比较:JDK 7 vs. JDK 8
      • 3. 实际开发中的应用场景与优化
    • 接口中的默认方法与静态方法
    • 新时间日期API
    • Try-with-Resources 升级
    • 重复注解与类型注解
  • Java9新特性

  • Java10新特性

  • Java11新特性

  • Java12新特性

  • Java13新特性

  • Java14新特性

  • Java15新特性

  • Java新特性
  • Java8新特性
scholar
2024-08-24
目录

对反射的支持增强

# Java 反射的增强与性能优化

前言

Java 反射(Reflection)在开发中广泛用于动态创建对象、调用方法、访问属性等。虽然灵活,但由于其性能开销较大,一直被视为影响系统效率的因素之一。Java 8 及之后的版本在反射方面进行了性能优化,使得在创建对象、对象赋值和反射调用方面有了显著的提升。

  • 1. 反射简介与应用场景
  • 2. Java 反射的性能优化
    • 性能比较:JDK 7 vs. JDK 8
  • 3. 实际开发中的应用场景与优化

# 1. 反射简介与应用场景

反射允许在运行时获取类的信息(如类的结构、方法、字段等),并且可以在不提前知道类的情况下动态地进行对象创建、方法调用和属性访问。这在框架设计、工具开发和通用性强的库中尤为重要,比如 Spring 框架的依赖注入、ORM 框架中的动态映射等。

常见应用场景:

  • 动态创建对象:通过反射创建不确定类型的对象。
  • 动态方法调用:可以调用未知类的任意方法。
  • 动态访问属性:可以读取和修改对象的私有字段。

# 2. Java 反射的性能优化

在 Java 7 和 Java 8 中,反射的性能有了显著的提升。Java 8 引入了更加高效的字节码操作,并对反射调用进行了优化,使得对象创建、属性设置和方法调用的性能得到了显著提高。

# 性能比较:JDK 7 vs. JDK 8

在相同的代码下,Java 8 的反射性能明显优于 Java 7。

代码示例:

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

// 测试反射性能的类
public class ReflectionPerformanceTest {
    private static final int loopCnt = 1000 * 1000 * 1000; // 循环次数设为10亿次

    public static void main(String[] args) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        System.out.println("Java version: " + System.getProperty("java.version"));

        createNewObject();
        assignValueToObject();
        reflectCreateAndAssignValue();
    }

    // 定义 Person 类用于测试
    static class Person {
        private Integer age = 20;

        public Integer getAge() {
            return age;
        }

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

    // 1. 循环创建新对象
    public static void createNewObject() {
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < loopCnt; i++) {
            Person person = new Person(); // 每次创建新对象
            person.setAge(30);
        }
        long endTime = System.currentTimeMillis();
        System.out.println("循环十亿次创建对象所需的时间:" + (endTime - startTime) + " ms");
    }

    // 2. 为同一个对象重复赋值
    public static void assignValueToObject() {
        long startTime = System.currentTimeMillis();
        Person person = new Person(); // 创建一个对象
        for (int i = 0; i < loopCnt; i++) {
            person.setAge(10); // 为同一个对象循环赋值
        }
        long endTime = System.currentTimeMillis();
        System.out.println("循环十亿次为同一对象赋值所需的时间:" + (endTime - startTime) + " ms");
    }

    // 3. 通过反射创建对象并赋值
    public static void reflectCreateAndAssignValue() throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        long startTime = System.currentTimeMillis();
        Class<Person> personClass = Person.class; // 获取类对象
        Person person = personClass.newInstance(); // 通过反射创建对象
        Method setAgeMethod = personClass.getMethod("setAge", Integer.class); // 获取 setAge 方法对象
        for (int i = 0; i < loopCnt; i++) {
            setAgeMethod.invoke(person, 90); // 通过反射调用方法并赋值
        }
        long endTime = System.currentTimeMillis();
        System.out.println("循环十亿次反射创建对象所需的时间:" + (endTime - startTime) + " ms");
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63

性能测试结果:

在 Java 8 中,反射调用的时间较 Java 7 显著缩短。测试结果如下:

  • Java 8:

    • 循环十亿次创建对象所需时间:9 ms
    • 循环十亿次为同一对象赋值所需时间:59 ms
    • 循环十亿次反射创建对象所需时间:2622 ms
  • Java 7:

    • 循环十亿次创建对象所需时间:6737 ms
    • 循环十亿次为同一对象赋值所需时间:3394 ms
    • 循环十亿次反射创建对象所需时间:293603 ms

# 3. 实际开发中的应用场景与优化

在实际开发中,反射的使用场景非常广泛,特别是在框架设计和工具开发中。然而,由于其性能开销,通常需要谨慎使用。以下是一些反射优化和使用建议:

  1. 减少不必要的反射调用:在性能敏感的场景中,尽量避免频繁使用反射。可以考虑将反射调用的结果缓存起来,避免重复调用。
  2. 使用新特性代替反射:Java 8 引入了 MethodHandle 和 LambdaMetaFactory 等更高效的替代方案,这些特性在某些场景下可以比传统的反射更加高效。
  3. 并发与多线程:在并发环境下,频繁使用反射可能导致性能瓶颈,建议在并发场景中结合 Fork/Join 框架等新特性优化反射调用。

总结

反射提供了强大的灵活性,特别是在框架和工具的设计中。随着 Java 版本的更新,反射的性能逐步优化,尤其在 Java 8 中,反射的时间开销得到了显著降低。然而,即使如此,在性能敏感的应用场景中,仍需权衡反射的使用,合理选择其他替代方案,如直接调用、缓存等。

编辑此页 (opens new window)
上次更新: 2024/12/28, 18:32:08
Optional 类的使用
接口中的默认方法与静态方法

← Optional 类的使用 接口中的默认方法与静态方法→

Theme by Vdoing | Copyright © 2019-2025 程序员scholar
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式