zoukankan      html  css  js  c++  java
  • effective解读-第六条 避免创建不必要对象

    1. 对于轻量级对象,由于现代版本的JVM对该类对象创建和回收十分的廉价,通过创建附加的对象提高程序的清晰性、简洁性和功能性,通常是件好事。

    2. 对于重量级对象(例如数据库连接对象)、大量创建的对象、不必要的对象(已存在对象已经能完成功能了但是又去创建了对象,而且对1中清晰性、简洁性和功能性没有任何帮助)要有限考虑避免创建重复对象

      反例1:使用String s=new String("bikini");在一个使用频繁的方法中或者循环中会创建很多没必要的对象。改进版本:String s="bikini";

      反例2: Boolean(String),同时提供构造器和静态工厂方法的不可变类,优先使用静态工厂方法以避免创建不必要的对象。改进:Boolean.valueOf(String)`替代,该构造器在java9中废弃。

      反例3:使用正则判断字符串是否匹配罗马字符,如果多次调用该方法就会降低程序性能,因为创建Pattern的成本很高

      static boolean isRomanNumeral(String str){
      return s.matches("^(?=.)M*(C[MD]|D?C{0,3})(X[CL]|L?X{0,3})(I[XV]|V?I{0,3})$")
      }

      改进版本:

      private static final Pattern ROMAN=Pattern.compile("^(?=.)M*(C[MD]|D?C{0,3})(X[CL]|L?X{0,3})(I[XV]|V?I{0,3})$");
      static boolean isRomanNumeral(String s){
      return ROMAN.matcher(s).matches();
      }

      书中还提到上面的代码可以编程懒加载模式,但是不建议这么做,因为它增加了代码的复杂性但是不能显著的提高到已有的性能水平。我们在编译器中写入下面的代码,代码检测工具也会提示我们这个问题(提示:在使用正则表达式时,利用好其预先编译功能,可以有效的加快正则匹配速度)。

      //不建议代码
      private final Pattern ROMAN;
      static boolean isRomanNumeral(String s){
      if(ROMAN==NULL){
       ROMAN=Pattern.compile("^(?=.)M*(C[MD]|D?C{0,3})(X[CL]|L?X{0,3})(I[XV]|V?I{0,3})$");
      }
      return ROMAN.matcher(s).matches();
      }

      反例4:要优先使用基本类型而不是装箱基本类型,要当心无意识的自动装箱,这里给出了创建多余实例的例子

      private static long sum(){
      //由于这里使用Long而没使用long 导致创建了2的31次方个Long实例
      Long sun=0L;
      for(long i=0;i<=Integer.MAX_VALUE;i++){
        sum+=i;
      }
      return sum;
      }

      正例1:不可变对象可以被安全的重用,这里提到了适配器模式中用来代替原功能对象的后备对象,由于它设计出来就是完成特定功能的,所以把它设计成可重用对象。

      正例2:Map保存key存储的例子,Map集合保存key的Set集合keySet,创建多个实例并无害处,但是没有必要,所以Map实例中keySet使用的是单例。

      HashMap map = new HashMap<>();
      map.put(1, 1);
      map.put(2, 2);
      map.put(3, 3);
      map.put(4, 4);
      Set set1= map.keySet();
      System.out.println(set1);
      map.put(5, 5);
      Set set2 = map.keySet();
      System.out.println(set1);
      System.out.println(set2);
      //true
      System.out.println(set1==set2);


      //源码如下
      public Set<K> keySet() {
      Set<K> ks = keySet;
      if (ks == null) {
        ks = new KeySet();
        keySet = ks;
      }
      return ks;
      }

     

     

    作者:刘志红

    -------------------------------------------

    个性签名:独学而无友,则孤陋而寡闻。做一个灵魂有趣的人!

    如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,博主在此感谢!

  • 相关阅读:
    2.HTML案例二 头条页面
    1.HTML入门
    33.1.网络编程入门
    32.原子性
    【转】风控中的特征评价指标(一)——IV和WOE
    【转】Python调用C语言动态链接库
    基于蒙特卡洛树搜索(MCTS)的多维可加性指标的异常根因定位
    正则表达式全集
    基于ray的分布式机器学习(二)
    基于ray的分布式机器学习(一)
  • 原文地址:https://www.cnblogs.com/chengxuyuan-liu/p/14584961.html
Copyright © 2011-2022 走看看