Java 反射 和 Java new 的效率有什么区别,亲测相差100倍

开发 前端
在我们的日常使用中,Java new是用的最多的,但是有些框架往往会使用Java反射来实现灵活性,那么它们之间的效率有什么区别呢?

我们的日常使用中,Java new是用的最多的,但是有些框架往往会使用Java反射来实现灵活性,那么它们之间的效率有什么区别呢?

你有没有想过,什么时候应该该用new来创建对象,什么时候该使用反射呢?

两者之间创建对象的效率如何?

ReflectDemo reflectDemo = new ReflectDemo();
Class<ReflectDemo> reflectDemoClass = ReflectDemo.class;
Class<?> aClass = Class.forName ("com.jason.sample.ReflectDemo");
Class<? extends Class> aClass = reflectDemoClass.getClass ();

1. new 对象和反射创建对象的效率对比

public class ReflectDemo {
public static void main (String[] args) throws IllegalAccessException, InstantiationException {
proxyObject();
newObject();
}

public static void newObject(){
long startTime = System.currentTimeMillis ();
int i;
for (i = 0; i < 100000000; i++) {
ReflectDemo reflectDemo = new ReflectDemo ();
}
if (i == 100000000) {
long endTime = System.currentTimeMillis ();
System.out.println ("new time:" + (endTime - startTime));
}
}

public static void proxyObject() throws IllegalAccessException, InstantiationException {
long startTime = System.currentTimeMillis ();
Class<ReflectDemo> reflectDemoClass = ReflectDemo.class;
int i;
for (i = 0; i < 100000000; i++) {
ReflectDemo reflectDemo = reflectDemoClass.newInstance ();
}
if (i == 100000000) {
long endTime = System.currentTimeMillis ();
System.out.println ("reflection time:" + (endTime - startTime));
}
}
}

new time:3
reflection time:230

最后我们发现新建1亿个对象和反射创建1亿个对象的效率相差很多倍。

那么让我们来探讨一下为什么会有如此大的差异。

一般来说,我们的Java代码需要在虚拟机上编译运行。

一般通过前端编辑器将java文件转换成class文件,比如javac.

接下来,在程序执行期间,JIT(即时编译器)可以将字节码文件转换为计算机可识别的机器码文件。另一种方式是通过 AOT 编译器直接将 java 文件编译成本地机器码文件。其中JIT会在程序运行时对程序进行优化,但是反射是通过动态分析的,所以可能无法对Java虚拟机进行一些优化。

​总结起来有以下几个原因:

  1. 反射需要动态解析类信息:在使用反射创建对象时,需要使用Class.forName()方法或类的class属性等方式获取类的信息。这个过程需要在运行时进行,而使用new关键字则在编译时已经解析了类信息,所以不需要进行类信息解析。
  2. 反射需要查找并调用构造函数:使用反射创建对象需要先获取构造函数对象,然后通过反射调用构造函数进行对象创建。这个过程需要在运行时进行,而使用new关键字则直接调用构造函数进行对象创建,无需查找构造函数。
  3. 反射需要进行安全性检查:使用反射创建对象时,Java会对代码进行安全性检查,以确保反射调用的方法和构造函数是可访问的。这个过程也需要在运行时进行,而使用new关键字则不需要进行安全性检查。
  4. 反射创建的对象需要做额外的初始化工作:使用反射创建的对象需要进行额外的初始化工作,例如调用对象的setAccessible(true)方法以访问私有成员变量和方法等。这些额外的操作也会增加反射创建对象的时间。

综上所述,Java反射比使用new关键字创建对象的性能差,因为反射需要在运行时进行更多的操作,包括动态解析类信息、查找并调用构造函数、进行安全性检查和进行额外的初始化工作等。在性能要求较高的场景中,应该尽可能地避免使用反射创建对象,而尽量使用new关键字进行对象创建。

2、反射的使用场景

反射的一些使用场景

  • 框架设计:Java反射可以在框架设计中使用,例如Spring框架中就广泛地使用了反射技术,可以根据注解或配置文件动态地加载和实例化对象,而不需要手动创建对象。
  • 测试工具:Java反射可以用于编写测试工具,例如JUnit框架就使用反射来执行测试方法,并获取测试结果等信息。
  • 插件化:Java反射可以用于插件化开发,可以通过反射获取插件中的类、方法、属性等信息,从而实现插件化功能。
  • 动态代理:Java反射可以用于动态代理技术中,可以动态地生成代理类,并在代理类中调用被代理对象的方法,从而实现代理功能。
  • 序列化和反序列化:Java反射可以用于序列化和反序列化操作,例如在Jackson和Gson等JSON解析库中就使用了反射技术,可以自动地将JSON字符串转换为Java对象,或者将Java对象转换为JSON字符串。
责任编辑:华轩 来源: 今日头条
相关推荐

2020-03-09 20:56:19

LoRaLoRaWAN无线技术

2022-09-07 18:32:57

并发编程线程

2020-11-09 14:07:53

PyQtQt编程

2022-09-08 18:38:26

LinuxWindowsmacOS

2022-06-06 14:53:02

LoRaLoRaWAN

2022-08-31 08:33:54

Bash操作系统Linux

2022-08-02 08:23:37

SessionCookies

2022-02-27 15:33:22

安全CASBSASE

2021-05-16 14:26:08

RPAIPACIO

2021-12-17 14:40:02

while(1)for(;;)语言

2024-03-05 18:59:59

前端开发localhost

2018-07-20 14:00:51

LinuxmacOS内核

2024-02-20 08:45:13

双大括号建立Java Map通用的模式

2023-12-15 09:21:17

ObjectJavaString

2022-08-22 07:06:32

MyBatisSQL占位符

2020-08-02 23:20:36

JavaScriptmap()forEach()

2020-06-28 15:11:07

LoRaWAN网络专用网络

2021-03-27 10:56:17

promisethenfinally

2022-08-03 07:04:56

GETHTTPPOST

2021-09-06 10:45:18

XDRMDR
点赞
收藏

51CTO技术栈公众号