考虑用静态构造方法代替构造器的好处:
1、静态构造方法有名字
    BigInteger.probablePrime(int, int, Random)比 new BigInteger(int, int, Random)更加清楚,从名字知道返回可能是素数。
    如果没有名字,将来给别人调用时,对方往往不知道该用哪个。
2、可以不必在每次调用时重新创建一个新对象
    其实就是享元模式和单例模式
3、可以返回原类型的任何子类型对象。
    这样可以使API变得更加简洁
    这里可以引申到“服务提供者框架模式”,类似于JDBC
4、创建参数化类型实例时,代码变得更简洁
    比如Map<String, List<String>> map = new HashMap<String, List<String>>();
    如果JDK有提供如下方法的话:
 public static <K, V> Map<K, V> newInstance(){
       return new HashMap<K,V>();
 }
可以直接Map<String, List<String>> map  = newInstance();

不过现在的JDK还没有这个方法。

 
考虑用静态构造方法代替构造器的坏处:
1、由于使用静态构造方法,会把原来的构造器去掉,造成这个类将无法被继承。
    不过这样倒也正好鼓励使用复合,而非继承。
2、它与其他普通的静态方法没有区别,文档或者一些工具,无法自动区分出这是构造方法。
    如果有人要查这个类的构造方法,将很难找。
 
 
 
参数多的时候,并且有些参数是可选的,builder模式更好
 
 
关于单例模式的强化:
传统的单例模式会被反射破坏掉,可以在构造器里计数,如果创建第二次则抛异常。
传统的单例模式会在序列化和反序列化之后变成两个,需要重写readResolve方法,返回原来的单例
 
单例模式的最佳方法:单元素枚举,可以解决上述两个问题。
 
 
避免创建不必要的对象:
1、比如,String s = new String("abc"); 应该改成 String s = "abc";
2、更倾向于使用静态构造器,比如:Boolean.valueOf(String)替代new Boolean(String),因为前者内部有复用对象,后者肯定会产生一个新对象。
3、明知不会改变的对象,要复用。比如判断时间是否落在某个起止时间之间,这里的起止时间是固定的,不需要每次判断时生成。
4、Map的keySet每次返回的是同一个Set,所以产生多个也没害处,却也是没有必要的。
5、优先使用基本类型(int),虽然包装类(Integer)用起来和基本类型几乎无差别,但其中隐式的包装和解包装会比较耗性能。
 
 
WeakHashMap : 当key被除了map本身引用之外,再无别的地方引用时,该key会被自动删除。
 
缓存以及回调等容易引起内存泄漏的地方,推荐使用WeakHashMap,弱引用的方式。
 
 
大部分情况下,避免使用finalizer方法:
1、因为finalizer方法被执行的时间是不确定的,甚至有可能根本不执行。
    比如在finalizer方法里做关闭文件的动作是错误的,因为对象失去引用后到执行finalizer的时间不确定,所以文件不会被及时关闭。
2、finalizer在不同JVM上执行的时机也未必相同。
    有可能在开发测试时的JVM上表现很好,但到了现场的JVM表现就很差,不稳定。
3、System.gc与System.runFinalization只能增加finalizer被执行的机会,但仍然是不确定的。
4、System.runFinalizationOnExit以及Runtime.runFinalizersOnExit能保证finalizer一定被执行,但这两个方法有致命缺陷,已经被废弃。
5、未被捕获的异常在finalizer过程中抛出是会被忽略的,甚至连警告都不会打印出来。
6、使用finalizer有一个非常严重的性能损失,创建和销毁对象比原来慢很多
 
不使用finalizer,可以使用显示的终结方法,典型的比如InputStream的close方法,要求调用者必须在结束时调用。
但finalizer可以充当显示终结方法的"安全网",在调用者忘记调用显示终结方法时,可以在finalizer里执行,因为这个时候调用者已经忘记了,即使finalizer的执行很不稳定,那也比没有关闭一些资源要好。比如FileInputStream就是采用这种“安全网”。
 
finalizer的另一个合理的用途是,对本地对象(native object)的回收资源,本地对象比较特殊,垃圾回收器是不会回收本地对象,所以需要调用finalizer来回收非关键资源。
 
 
 

EffectiveJava笔记(第一部分)的更多相关文章

  1. 《javascript权威指南》读书笔记——第一篇

    <javascript权威指南>读书笔记——第一篇 金刚 javascript js javascript权威指南 由于最近想系统学习下javascript,所以开始在kindle上看这本 ...

  2. ActionBarSherlock学习笔记 第一篇——部署

    ActionBarSherlock学习笔记 第一篇--部署          ActionBarSherlock是JakeWharton编写的一个开源框架,使用这个框架,可以实现在所有的Android ...

  3. C++ Primer 笔记 第一章

    C++ Primer 学习笔记 第一章 快速入门 1.1 main函数 系统通过调用main函数来执行程序,并通过main函数的返回值确定程序是否成功执行完毕.通常返回0值表明程序成功执行完毕: ma ...

  4. Android开发艺术探索笔记——第一章:Activity的生命周期和启动模式

    Android开发艺术探索笔记--第一章:Activity的生命周期和启动模式 怀着无比崇敬的心情翻开了这本书,路漫漫其修远兮,程序人生,为自己加油! 一.序 作为这本书的第一章,主席还是把Activ ...

  5. Android群英传笔记——第一章:Android体系与系统架构

    Android群英传笔记--第一章:Android体系与系统架构 图片都是摘抄自网络 今天确实挺忙的,不过把第一章的笔记做一下还是可以的,嘿嘿 1.1 Google的生态圈 还是得从Android的起 ...

  6. Scala语言笔记 - 第一篇

    目录 Scala语言笔记 - 第一篇 1 基本类型和循环的使用 2 String相关 3 模式匹配相关 4 class相关 5 函数调用相关 Scala语言笔记 - 第一篇 ​ 最近研究了下scala ...

  7. oracle学习笔记第一天

    oracle学习笔记第一天 --oracle学习的第一天 --一.几个基础的关键字   1.select select (挑选) 挑选出显示的--列--(可以多列,用“,”隔开,*表示所有列),为一条 ...

  8. [编程笔记]第一章 C语言概述

    //C语言学习笔记 第一讲 C语言概述 第二讲 基本编程知识 第三讲 运算符和表达式 第四讲 流程控制 第五讲 函数 第六讲 数组 第七讲 指针 第八讲 变量的作用域和存储方式 第九讲 拓展类型 第十 ...

  9. 《Linux内核设计与实现》读书笔记——第一、 二章

    <Linux内核设计与实现>读书笔记--第一. 二章 标签(空格分隔): 20135321余佳源 第一章 Linux内核简介 1.Unix内核特点 十分简洁:仅提供几百个系统调用并且有明确 ...

随机推荐

  1. Inventory Pro 装备拾取的实现

    以后都按照插件使用,提出问题,回答问题的方式来进行总结和学习 效果图 1.运行相关的例子,场景中出现4个矩形,这4个矩形是用来模拟物品掉落的包裹,移动Player靠近物品 2.使用鼠标点击物品正方体, ...

  2. F面经prepare:strstr变种

    * Given an integer k>=1 and two strings A and B (length ~n each); * Figure out if there is any co ...

  3. Python学习总结16:时间模块datetime & time & calendar (三)

    calendar模块 常见函数及说明 1 calendar.calendar(year,w=2,l=1,c=6)   返回一个多行字符串格式的year年年历,3个月一行,间隔距离为c. 每日宽度间隔为 ...

  4. SOL面向对象 五大原则

    单一职责原则SRP(Single Responsibility Principle)是指一个类的功能要单一,不能包罗万象.如同一个人一样,分配的工作不能太多,否则一天到晚虽然忙忙碌碌的,但效率却高不起 ...

  5. js正则表达式进行格式校验

    今天做了个js正则表达式的练习,利用正则表达式进行注册信息格式验证,注册信息界面如下: 格式要求: 1.学号项不能为空,必须为纯数字,不能与数据库中的重复,正则表达式/^\d+$/g: 2.姓名项不能 ...

  6. Demo13

    this.listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void o ...

  7. log4net 使用教程

    1.下载log4net (Google log4net) //已有 2.unzip log4net 3.运行VS,新建 c# Windows应用程序. 4.添加引用Log4NET 5.新建一个应用程序 ...

  8. paper 50 :人脸识别简史与近期进展

    自动人脸识别的经典流程分为三个步骤:人脸检测.面部特征点定位(又称Face Alignment人脸对齐).特征提取与分类器设计.一般而言,狭义的人脸识别指的是"特征提取+分类器"两 ...

  9. -Xloggc:log/gc.log 指定GC log的位置

    -Xloggc:log/gc.log指定GC log的位置,以文件输出帮助开发人员分析问题

  10. Linux centOS7 下安装mysql5.7.10

    1:下载二进制安装包 http://cdn.mysql.com//Downloads/MySQL-5.7/mysql-5.7.10-linux-glibc2.5-x86_64.tar.gz 2:解压到 ...