首页 > 编程语言 >effective java读后感1(1-5点)

effective java读后感1(1-5点)

时间:2023-06-09 10:08:31浏览次数:42  
标签:读后感 java effective 对象 demo 实例 Demo public 构造函数


effective java中提供了57条建议。针对这些建议,我谈谈自己的理解。


1.考虑用静态工厂方法代替构造函数

静态工厂方式相比于构造函数的两个优点:

1)可以有符合自己身份的方法名,方便客户端代码的阅读

2)调用的时候,不要求创建一个新的实例。可以返回缓存实例,或者singleton实例等


静态工厂方法的最大缺点:

如果类中没有public或者protected的构造函数,使用静态工厂方法的方式得到实例,那么这个类就无法被继承。

比如

public   class  Demo {
     private   static  Demo demo  =   new  Demo();

     public   static  Demo getInstance() {
         return  demo;
    }

     private  Demo() {
    }
}

那么这个类就无法被继承。

(当然,鼓励使用组合,而不是继承)


在spring没有流行起来的那些日子里,我大量使用工厂方法,但是使用spring等ioc容器后,这一切都是交给容器去处理了。或许,在客户端代码中,工厂模式会因为这些ioc的出>现,而遭受淘汰。



2.使用私有构造函数强化singleton属性

一旦存在public或者protected的构造函数,那么无法保证一个类,一定是sinleton的。因为无法得知客户端代码是使用构造函数,还是同构静态方法去得到类实例。所以对于一个严格要求singleton的类,那么其构造函数必须是私有的。

既然说到singleton了,那么顺便说下几个常见的创建方法

1)
/**
 * 优点:简单,而且可以确保一定是singletion实例
 * 缺点:类加载时,就会初始化实例,不能做到延迟初始化。
  */
public   class  Demo {
     private   static final Demo demo  =   new  Demo();

     public   static  Demo getInstance() {
         return  demo;
    }

     private  Demo() {
    }
}
2)
/**
 * 优点:lazy load(延迟初始化实例),提高效率
 * 缺点:多线程情况下,可能初始化多份实例
  */
public   class  Demo {
     private   static  Demo demo  =   null ;

     public   static  Demo getInstance() {
         if (demo   ==   null  ) {
            demo  =   new  Demo();
        }
         return  demo;
    }

     private  Demo() {
    }
}
3)
/**
 * 优点:lazy load(延迟初始化实例),提高效率
 *              采用double check并且同步的方式,理论上确保在多线程的应用场景中,也只创建一份实例
 * 备注:(涉及到jvm的实现,在实际应用中,也可能生成多份实例,但是几率是相当地低)
  */
public   class  Demo {
     private   static  Demo demo  =   null ;

     public   static  Demo getInstance() {
         if (demo   ==   null  ) {
             synchronized (Demo. class )  {
                 if (demo  ==   null ) {
                    demo  =   new  Demo();
                }
            }
        }
         return  demo;
    }

     private  Demo() {
    }
}

3.使用私有构造函数强化不可实例化能力

咋一看这个标题,觉得不可思议,居然让类不具备实例化能力。但是确实也有一些应用场景,比如一些util类,就不需要实 例化。但是有很大的副作用,就是类无法被继承。所以换成我,就算是util类,我还是会保留其public的构造函数的。客户端就算要实例化这些 util,也无伤大雅。



4.避免创建重复对象

一般情况下,请重复使用同一个对象,而不是每次需要的时候创建一个功能上等价的新对象。这主要是为了性能上的考虑,何况在一般的应用场景下,确实没有必要去重复创建对象。当然有时候为了OO设计考虑,也不特别排斥创建重复的小对象。

需要明确的是,避免创建重复的对象,请不要产生一个误区就是:创建对象的成本非常昂贵。事实上,创建小对象的开销是非常小的,而且现在的jdk gc对于小对象的GC代价也是非常廉价(在之后的日子里,我会针对sun jdk gc,做一次介绍)。比如在做Swing开发的时候,会创建很多EventListener对象,比如在Spring Framework中,就创建很多匿名内隐类对象实现类似ruby等动态语言的Closure(闭包)。

但是也不可否认的是,创建大对象,对大对象的GC 的开销是比较大的。比如初始化一个对象的时候,需要加载10m的文件内容到内存;创建数据库连接对象等等,在这些场景下,创建的开销是相当昂贵了,一定要尽可能避免重复对象的创建(除非特殊需求)。

对于这些大对象,一般采用singleton模式,cache,或者object pool等方式,避免重复的创建。至于采用具体什么方式,需要根据具体的应用场景来决定了。



5.消除过期对象的引用

为什么要这么做?其实只要理解“java内存泄露”这个概念就可以了。java中的内存泄漏不同于C++中的内存泄漏。 C++是需要程序员手工管理内存的语言,创建一个对象,用完之后,需要手工删除这个对象。而java不一样,jdk gc替程序员做了这件事情,一旦对象失去了引用之后,jdk gc就会自动回收这个对象。

为了避免java中的内存泄漏,只需要知道一点就可以:对于无用的对象,必须消除对这个对象的引用。

怎么消除对象的引用呢?难道需要手工设置“object=null;”,那么一旦程序中到处充斥着这样的代码,将会是一件非常恶心的事情,严重影响程序的阅读性。

正确的做法是,每个定义的变量给予最紧凑的作用域,一旦对象结束生命周期,自然就消除了对其的引用。

当然在必要的场合,也不反对采用清空对象引用的方法,但是不推荐。

内存泄漏的症状不能在短时间内反应出来,往往是在程序运行一段时间,一天,一周,一个月,甚至一年,才逐渐显现的,一个经验丰富的程序员,也不能确保其代 码一定不存在内存泄漏的问题。检查内存泄漏问题,往往需要借助工具,heap profile,比如jprofile等等。在linux下面,可以使用jps jstat jinfo jmap等命令去观察。


标签:读后感,java,effective,对象,demo,实例,Demo,public,构造函数
From: https://blog.51cto.com/u_16065168/6445444

相关文章

  • Java各种路径和参数
    1.JSP中获得当前应用的相对路径和绝对路径:根目录所对应的绝对路径:request.getRequestURI()文件的绝对路径:application.getRealPath(request.getRequestURI());当前web应用的绝对路径:application.getRealPath("/");取得请求文件的上层目录:newFile(application.getRealP......
  • Java利用xml将大批量数据导出到excel的一个方法
    笔者在Java开发中常常会遇到将数据库数据导出到Excel的要求,比如在我的一个项目中,客户要求所有查询结果都可以导出到Excel,对于数据量不大的(几万条),这比较容易实现,但对于数据量比较大的(几十万及以上,具体要看导出内容的字段个数和长短),则在数据库查询和生成excel文件上都会有麻烦。......
  • [从jQuery看JavaScript]-变量与作用域链(Variable and Scope Chain)
    jQuery片段: 1.var2.//Willspeedupreferencestowindow,andallowsmungingitsname.3.window=this,4.//Willspeedupreferencestoundefined,andallowsmungingitsname.5.undefined,6.//MapoverjQueryinc......
  • 如何设置Java开发环境
    如果您是Java开发人员,那么设置高效的Java开发环境是关键。它有助于简化您的编码过程并提高您的工作效率。在本文中,我将带您完成设置Java开发环境所需的重要步骤。我们将介绍如何安装Java开发工具包(JDK)、集成开发环境(IDE)以及配置必要的工具和库。让我们开始吧!(更多......
  • 读后感——人月神话
    《人月神话:软件项目管理之道》(英语:The Mythical Man-Month: Essays on Software Engineering)是由IBM System/360系统之父佛瑞德·布鲁克斯所著经典文集,全书讲解软件工程、项目管理相关课题,被誉为软件领域的圣经,内容源于作者布鲁克斯在IBM公司System/360家族和OS/360中的项......
  • 【Java技术专题】「Guava开发指南」手把手教你如何进行使用Guava工具箱进行开发系统实
    Guava中的Preconditions(前置条件判断)Preconditions(前置条件):让方法调用的前置条件判断更简单。Guava在Preconditions类中提供了若干前置条件判断的实用方法,我们强烈建议在Eclipse中静态导入这些方法。每个方法都有三个变种:当方法没有额外参数时,抛出的异常中不包含错误消息,这会使......
  • Java Kafka简单地将Map对象序列化为json
    最近用到kafka,想简单地把Map对象序列化为json发送到主题,直接用string序列化,生成的结果不是json,虽然格式很像,key都没有引号,可能是直接调用的toString方法。但是网上搜了一圈,都是spring组合或者其他不太简单的方案。在哔站看了一段视频受到启发,就实现了一个自定义json序列化类,......
  • 【Java查漏补缺(一)】数组与循环
    除了数组与循环,还有方法,讲究看吧!后续练习内容都是连贯的!BasicalJava看下Java中的变量类型吧!数据类型关键字内存占用二进制位数字节型byte1个字节4位短整型short2个字节8位整型int(常用)4个字节32位长整型long8个字节64位单精度浮点数float......
  • Java_Collections.EMPTY_LIST
     1.背景在某些情况下,我们经常需要发挥一个空的集合对象,比如说在数据查询时,并不需要发挥一个NULL或是异常,那么就可以返回一个空的集合对象。如果你想new一个空的List,而这个List以后也不会再添加元素,那么就用Collections#emptyList()好了。newArrayList()或者newLinked......
  • Java_Timer
     Java_Timer ava.util.Timer是一个实用工具类,该类用来调度一个线程,使它可以在将来某一时刻执行。Java的Timer类可以调度一个任务运行一次,或定期运行。 java.util.TimerTask是一个抽象类,它实现了Runnable接口。我们需要扩展该类以便创建自己的TimerTask,这个TimerTask内部使用jav......