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

文章目录


一、基础概念

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

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

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

java 复制代码
//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 对象和反射创建对象的效率对比

java 复制代码
//测试代码如下
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必须要知道类名,而反射创建对象不需要知道类型也可以创建
相关推荐
Scott9999HH7 小时前
【IIoT流量实战】蒸汽管道阀门全关却仍有流量?用 Python 实现涡街信号 FFT 频谱分析与温压全补偿积算网关,深度拆解靠谱的涡街流量计厂家硬核技术标准
开发语言·python
腻害兔7 小时前
【若依项目-产品经理视角】深度拆解 RuoYi-Vue-Pro 商城模块:从商品管理到交易引擎,50 张表撑起一整套电商系统
java·大数据·vue.js·产品经理·ai编程
码智社8 小时前
AES加密原理详解及Java实现加解密实战
java·开发语言
AI云海8 小时前
python 列表、元组、集合和字典
开发语言·python
萧瑟余晖9 小时前
JDK 26 新特性详解
java·开发语言
马优晨10 小时前
Freemarker 完整讲解(后端 Java 模板引擎)
java·开发语言·freemarker·freemarker 完整讲解·freemarker模板引擎
人邮异步社区12 小时前
怎么把C语言学到精通?
c语言·开发语言
心平气和量大福大12 小时前
C#-WPF-控件-TextBox 数据绑定
开发语言·c#·wpf
ttwuai12 小时前
Cursor 生成 CRUD 后,Go 后台接口别只测 200:JWT、RBAC 和 tenant_id 怎么验
开发语言·后端·golang
维天说13 小时前
CLI-Switch 2026年3月版历史设计:Hook、TTY 隔离与 JSON 状态
java·服务器·json