在Java中如何避免创建不必要的对象

 更新时间:2021年10月25日 09:27:15   作者:李子捌  
作为Java开发者,我们每天创建很多对象,但如何才能避免创建不必要的对象呢?这需要我们好好学习,这篇文章主要给大家介绍了关于在Java中如何避免创建不必要对象的相关资料,需要的朋友可以参考下

简介

在Java开发中,程序员要尽可能的避免创建相同的功能的对象,因为这样既消耗内存,又影响程序运行速度。在这种情况下可以考虑重复利用对象。

接下来举例几种对象重复利用的场景,看看我们是不是有中招了,如果有赶紧趁着还没被发现悄悄改掉,被发现了会被diss啦!

1、String和Boolean

如下两种写法看似没有什么区别,但是如果深入jvm底层了解,我们可以利用jvm运行时常量池的特性,避免创建具有相同功能的String对象(尤其是在循环内部创建)可以带来比较可观的性能优化以及节约内存。

错误写法

// 每次都会创建一个新的String对象,且不会加入常量池
String name2 = new String("李子捌");

正确写法

// 正确写法
String name1 = "李子捌";

除此之外,刚写Java代码的程序员们,也要正确的选择String、StringBuilder、StringBuffer类的使用。String为不可变对象,通常用于定义不变字符串;StringBuilder、StringBuffer用于可变字符串操作场景,如字符串拼接;其中StringBuffer是线程安全的,它通过Synchronized关键字来实现线程同步。

// StringBuffer中的append()方法
public synchronized StringBuffer append(String str) {
    toStringCache = null;
    super.append(str);
    return this;
}

// StringBuilder中的append()方法
public StringBuilder append(String str) {
    super.append(str);
    return this;
}

Boolean是常用的类型,在开发中也应该使用Boolean.valueof()而不是new Boolean(),从Boolean的源码可以看出,Boolean类定义了两个final static的属性,而Boolean.valueof()直接返回的是定义的这两个属性,而new Boolean()却会创建新的对象。

public static final Boolean TRUE = new Boolean(true);

public static final Boolean FALSE = new Boolean(false);

2、自动拆箱和装箱

Java提供了基本数据类型的自动拆箱和装箱功能,那是不是意味着我们可以在代码中随意的使用这两个类型呢?其实理论上在代码层面是没得问题,不过在具体的性能方面还是有优化的空间啦!!!

我们来测试下性能

long start = System.currentTimeMillis();
Integer sum = 0;
for (int i = 0; i < 100000; i++) {
    sum += i;
}
System.out.println(System.currentTimeMillis() - start);

使用Integer耗时3毫秒

long start = System.currentTimeMillis();
// 修改Integer 为 int 
int sum = 0;
for (int i = 0; i < 100000; i++) {
    sum += i;
}
System.out.println(System.currentTimeMillis() - start);

使用int耗时0毫秒

因此关于自动拆箱装箱的使用,我们其实也可以做适当的考虑,毕竟有时候代码性能就是一点点挤出来的嘛!!!

3、正则表达式

正则表达式我们经常用于字符串是否合法的校验,我们先来看一段简单的代码(大家有没有一眼看出问题呢?我想你肯定看出来了!!!):

public static void main(String[] args) {

    String email = "1057301174@qq.com";
    String regex = "^([a-z0-9A-Z]+[-|\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\.)+[a-zA-Z]{2,}$";

    long start = System.currentTimeMillis();
    for (int i = 0; i < 10000; i++) {
        email.matches(regex);
    }

    System.out.println(System.currentTimeMillis() - start);

}

执行这段代码的时间,一共耗时71毫秒,看似好像挺快的!

但是我们做个非常简单的优化,优化后的代码如下所示:

public static void main(String[] args) {

    String email = "1057301174@qq.com";
    String regex = "^([a-z0-9A-Z]+[-|\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\.)+[a-zA-Z]{2,}$";
    Pattern pattern = Pattern.compile(regex);

    long start = System.currentTimeMillis();
    for (int i = 0; i < 10000; i++) {
        //email.matches(regex);
        pattern.matcher(email);
    }

    System.out.println(System.currentTimeMillis() - start);

}

再次执行代码,一共耗时1毫秒,快了70倍呀!!!

这是因为String.matches()方法在循环中创建时,每次都需要执行Pattern.compile(regex),而创建Patter实例的成本很高,因为需要将正则表达式编译成一个有限状态机( finite state machine)。这种我们经常会因为Java api提供了比较方便的方法调用而忽略了性能考究,往往不容易被发现。这个时候就需要优秀的你,去“咬文嚼字”啦!

总结

到此这篇关于在Java中如何避免创建不必要对象的文章就介绍到这了,更多相关Java避免创建不必要对象内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 详解自动注册Gateway网关路由配置

    详解自动注册Gateway网关路由配置

    这篇文章主要为大家介绍了自动注册Gateway网关路由配置的方法详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-03-03
  • IDEA JeeSite框架httpSession.invalidate()无效问题解决方案

    IDEA JeeSite框架httpSession.invalidate()无效问题解决方案

    这篇文章主要介绍了IDEA JeeSite框架httpSession.invalidate()无效问题解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-09-09
  • java通过证书访问etcd的实现步骤

    java通过证书访问etcd的实现步骤

    Etcd提供了多种语言的客户端库,本文主要介绍了java通过证书访问etcd的实现步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-05-05
  • spring boot中多线程开发的注意事项总结

    spring boot中多线程开发的注意事项总结

    spring boot 通过任务执行器 taskexecutor 来实现多线程和并发编程。下面这篇文章主要给大家介绍了关于spring boot中多线程开发的注意事项,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2018-09-09
  • jdk中keytool的使用以及如何提取jks文件中的公钥和私钥

    jdk中keytool的使用以及如何提取jks文件中的公钥和私钥

    JKS文件由公钥和密钥构成利用Java Keytool工具生成的文件,它是由公钥和密钥构成的,下面这篇文章主要给大家介绍了关于jdk中keytool的使用以及如何提取jks文件中公钥和私钥的相关资料,需要的朋友可以参考下
    2024-03-03
  • SpringBoot 集成 activiti的示例代码

    SpringBoot 集成 activiti的示例代码

    这篇文章主要介绍了SpringBoot 集成 activiti的示例代码,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-10-10
  • Java线程休眠_动力节点Java学院整理

    Java线程休眠_动力节点Java学院整理

    sleep() 的作用是让当前线程休眠,即当前线程会从“运行状态”进入到“休眠(阻塞)状态”。下面通过实例代码给大家介绍Java线程休眠的知识,需要的朋友参考下吧
    2017-05-05
  • 学习Java中的List集合

    学习Java中的List集合

    这篇文章主要介绍了学习Java中的List集合,List是一个有序集合, 说是集合,其实只是只是Collection接口的一个子接口,下面关于List的相关资料 需要的小伙伴可以参考一下,希望对你有所帮助
    2022-02-02
  • 关于idea更新到2020.2.3无法创建web项目原因 library is not specified

    关于idea更新到2020.2.3无法创建web项目原因 library is not specified

    这篇文章主要介绍了关于idea更新到2020.2.3无法创建web项目原因 library is not specified,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-10-10
  • Java使用join方法暂停当前线程

    Java使用join方法暂停当前线程

    这篇文章主要为大家详细介绍了Java使用join方法暂停当前线程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-04-04

最新评论