Java反射和new效率对比,差距有多大?

简介: Java中,一般我们创建一个对象可能会选择new一下个实例。但是随着我们技术的不断提升,我们也学习到了,可以通过反射技术实现对象的创建。可是,你有没有想一下,什么时候我们改用new创建对象,什么时候我们改用反射创建对象呢?

一. 基础概念

Java中,一般我们创建一个对象可能会选择new一下个实例。但是随着我们技术的不断提升,我们也学习到了,可以通过反射技术实现对象的创建。

可是,你有没有想一下,什么时候我们改用new创建对象,什么时候我们改用反射创建对象呢?

两者创建对象的效率又是如何呢?

//new 方式创建对象
ReflectDemo reflectDemo = new ReflectDemo();
//反射创建对象  反射创建对象的三种方式
(1)Class<ReflectDemo> reflectDemoClass = ReflectDemo.class;
(2)Class<?> aClass = Class.forName ("com.whale.springtransaction.transactiondemo.reflectdemo.ReflectDemo");
(3)Class<? extends Class> aClass = reflectDemoClass.getClass ();

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

//测试代码如下
public class ReflectDemo {
 public static void main (String[] args) throws IllegalAccessException, InstantiationException {
  proxyObject();
  newObject();
 }
 //new 创建对象
 //5
 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耗时为:" + (endTime - startTime));
  }
 }
 //反射 创建对象
 //30
 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 ("反射耗时为:" + (endTime - startTime));
  }
 }
}

最终我们发现,new 100000000 个对象和反射创建 100000000 个对象,效率相差了很多倍。

所以下面我们来探讨一下为什么这么大差别?

首先第一点,一般我们的Java代码是需要编译后在虚拟机里面运行的。

我们一般都是通过一个前端编辑器,比如javac,把java文件转为class文件。

接下来,程序运行期间,可能会通过一个JIT,即时编译器将字节码文件转换为计算机认识的机器码文件。

另外一种可能是通过一个AOT编译器,直接把java文件编译为本地机器码文件。其中JIT在程序运行期会对程序进行优化,但是反射是通过动态解析的方式,因此可能无法执行某些java虚拟机的优化。

总结起来有下面几个原因:

Method#invoke 方法会对参数做封装和解封操作

  • 需要检查方法可见
  • 需要校验参数
  • 反射方法难以内联
  • JIT 无法优化

三. 反射和new 的使用场景

反射的部分使用场景

  1. Spring通过反射来帮我们实例化对象,并放入到Ioc容器中
  2. 使用JDBC链接数据库时加载数据库驱动Class.forName()
  3. 逆向代码 例如反编译
  4. 利用反射,在泛型为int的arryaList集合中存放一个String类型的对象

new 对象和反射的区别

  1. new的对象无法访问其中的私有属性,反射出来的可以通过设置setAccessible()方法来省略访问权限符。
  2. new必须要知道类名,而反射创建对象不需要知道类型也可以创建
  3. 本文就是愿天堂没有BUG给大家分享的内容,大家有收获的话可以分享下,想学习更多的话可以到微信公众号里找我,我等你哦。
相关文章
|
23天前
|
Java
【Java基础面试三十二】、new String(“abc“) 是去了哪里,仅仅是在堆里面吗?
这篇文章解释了Java中使用`new String("abc")`时,JVM会将字符串直接量"abc"存入常量池,并在堆内存中创建一个新的String对象,该对象会指向常量池中的字符串直接量。
|
8天前
|
Java API 调度
掌握Java线程状态:从NEW到TERMINATED
本文探讨了操作系统与Java中线程的状态及其转换。操作系统层面,线程状态包括初始、就绪、运行、阻塞和终止。Java线程状态则细分为NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING和TERMINATED,并详细介绍了各状态的特性和转换条件。此外,还列举了Java中常用的线程方法,如`wait()`、`notify()`、`start()`和`join()`等,帮助理解线程控制机制。
掌握Java线程状态:从NEW到TERMINATED
|
3天前
|
Java 程序员 编译器
Java的反射技术reflect
Java的反射技术允许程序在运行时动态加载和操作类,基于字节码文件构建中间语言代码,进而生成机器码在JVM上执行,实现了“一次编译,到处运行”。此技术虽需更多运行时间,但广泛应用于Spring框架的持续集成、动态配置及三大特性(IOC、DI、AOP)中,支持企业级应用的迭代升级和灵活配置管理,适用于集群部署与数据同步场景。
|
23天前
|
Java
【Java基础面试二十八】、使用字符串时,new和““推荐使用哪种方式?
这篇文章讨论了在Java中使用字符串时,推荐使用双引号`""`直接量方式而不是使用`new`操作符,因为`new`会在常量池之外额外创建一个对象,导致更多的内存占用。
|
2月前
|
安全 Java 测试技术
day26:Java零基础 - 反射
【7月更文挑战第26天】🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
29 5
|
22天前
|
缓存 安全 Java
【Java 第十篇章】反射
Java 反射技术让程序能在运行时动态获取类信息并操作对象,极大提升了灵活性与扩展性。本文将介绍反射的基本概念、原理及应用,包括如何使用 `Class`、`Field`、`Method` 和 `Constructor` 类进行动态操作。此外,还将探讨反射在动态加载、框架开发与代码测试中的应用场景,并提醒开发者注意性能与安全方面的问题,帮助你更合理地运用这一强大工具。
13 0
|
2月前
|
IDE Java 测试技术
Java进阶之反射
【7月更文挑战第14天】Java反射机制允许在运行时动态获取类信息、创建对象及调用其方法。它基于`Class`类,让我们能访问类的属性、方法、构造器。例如,通过`Class.forName()`加载类,`Class.newInstance()`创建对象,`Method.invoke()`执行方法。反射广泛应用于动态代理、单元测试、序列化及框架中,提供灵活性但牺牲了性能,且可破坏封装性。IDE的代码补全也是反射的应用之一。在使用时需谨慎,避免对私有成员的不当访问。
26 1
|
2月前
|
Java 程序员 测试技术
解析Java中的反射机制及其应用场景
解析Java中的反射机制及其应用场景
|
2月前
|
开发框架 Java Android开发
Java中的类反射与动态代理详解
Java中的类反射与动态代理详解
|
2月前
|
Java API
Java注解与反射机制
Java注解与反射概述: - 注解用于元数据,包括元注解`@Target`, `@Retention`, `@Documented`, `@Inherited`。 - 自定义注解用于自定义行为标记,参考[链接]例化后通过`getClass()`获取类信息。 - 主要API涉及类的多种获取方式,如`对象.getClass()`, `类名.class`, `Class.forName()`和内置类型`TYPE`。 - 应用场景包括动态创建对象,获取泛型和注解信息以及分析运行时结构。