《Effective Java》学习笔记

第1条:考虑用静态工厂方法代替构造器

【尚未彻底读懂笔者的意图】

第2条:遇到多个构造器参数时要考虑用构造器

1.使用重叠构造器:缺点是写太多

2.使用JavaBean模式:缺点是不一致

3.使用Builder模式:先创造构造器,太冗长

Builder模式:

 1 public class NutritionFacts{
 2     private final int servingSize;
 3     private final int servings;
 4     private final int calories;
 5     private final int fat;
 6     private final int sodium;
 7     private final int carbohydrate;
 8
 9     public static class Builder{
10         private final int servingSize;
11         private final int servings;
12
13         private int calories=0;
14         private int fat=0;
15         private int sodium=0;
16         private int carbohydrate=0;
17
18         public Builder(int servingSize,int servings){
19             this.servingSize=servingSize;
20             this.servings=servings;
21         }
22
23         public Builder calories(int value){
24             calories=value;
25             return this;
26         }
27
28         public Builder fat(int value){
29             fat=value;
30             return this;
31         }
32
33         public Builder sodium(int value){
34             sodium=value;
35             return this;
36         }
37
38         public Builder carbohydrate(int value){
39             carbohydrate=value;
40             return this;
41         }
42
43         public NutritionFacts build(){
44             return new NutritionFacts(this);
45         }
46
47     }
48
49     private NutritionFacts(Builder builder){
50         servingSize=builder.servingSize;
51         servings=builder.servings;
52         calories=builder.calories;
53         fat=builder.fat;
54         sodium=builder.sodium;
55         carbohydrate=builder.carbohydrate;
56     }
57
58     public static void main(String[] args){
59         NutritionFacts cocaCola=new NutritionFacts.Builder(240,8).calories(100).sodium(35).carbohydrate(27).build();
60         System.out.println("cocaCola nutritionfacts build success.");
61     }
62 }

第3条:用私有构造器或者枚举类型强化Singleton属性

1.公有静态成员是个final域:缺点是享有特权的客户端可以通过AccessibleObject.setAccessible方法,通过反射机制调用私有构造器

1 public class Elvis{
2     public static final Elvis INSTANCE=new Elvis();
3     private Elvis(){}
4 }

2.公有的成员是个静态工厂方法:

1 public class Elvis{
2     private static final Elvis INSTANCE=new Elvis();
3     private Elvis(){}
4     public static Elvis getInstance(){
5         return INSTANCE;
6     }
7 }

同时,在利用静态工厂方法实现Singleton类变成可序列化的,仅仅在声明上加上implements Serializable是不够的。为了维护并且保证Singleton,必须声明所有实例都是瞬时的,并且提供一个readResolve方法。否则,每次反序列化一个序列化的实例时,都会创建一个新的实例。【尚未清楚,为啥加了readResolve方法就能防止】

 1 public class Elvis{
 2     private static final Elvis INSTANCE=new Elvis();
 3     private Elvis(){}
 4
 5     public static Elvis getInstance(){
 6         return INSTANCE;
 7     }
 8
 9     private Object readResolve(){
10         return INSTANCE;
11     }
12 }

3.编写一个包含单个元素的枚举类型:

1 public enum Elvis{
2     INSTANCE;
3
4     public void leaveTheBuilding(){}
5 }

单元素的枚举类型已经成为了实现Singleton的最佳方法。

第4条:通过私有构造器强化不可实例化的能力:

1 public class UtilityClass{
2     private UtilityClass(){
3         throw new AssertionError();
4     }
5 }

第5条:避免创建不必要的对象1.通常使用静态工厂方法而不是构造器,以避免创建不必要的对象。

 1 class Person{
 2     private final Date birthDate;
 3     private static final Date BOOM_START;
 4     private static final Date BOOM_END;
 5
 6     static{
 7         Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
 8         gmtCal.set(1946,Calendar.JANUARY,1,0,0,0);
 9         BOOM_START=gmtCal.getTime();
10         gmtCal.set(1965,Calendar.JANURAY,1,0,0,0);
11         BOOM_END=gmtCal.getTime();
12     }
13
14     public boolean isBabyBoomer(){
15         return birthDate.compareTo(BOOM_START)>=0&&bithDate.compareTo(BOOM_END)<0;
16     }
17 }

2.

时间: 2024-10-12 15:09:35

《Effective Java》学习笔记的相关文章

疯狂Android讲义 - 学习笔记(二)

Android应用的用户界面编程 Android推荐使用XML布局文件来定义用户界面 ViewGroup是一个抽象类,通常使用它的子类作为容器,ViewGroup控制其子组件的分布依赖于两个内部类: ViewGroup.LayoutParams 和 ViewGroup.MarginLayoutParams 疯狂Android讲义 - 学习笔记(二),布布扣,bubuko.com

疯狂Android讲义 - 学习笔记(六)

第7章 7.1 使用简单图片 7.1.1 使用Drawable对象 7.1.2 Bitmap和BitmapFactory 7.2 绘图 7.2.1 Android绘图基础:Canvas.Paint等 Android的绘图应该继承View组件,并重写onDraw(Canvas canvas) 方法即可,Canvas代表了“依附”于指定View的画布.表7.1 Canvas的绘制方法 Paint代表了Canvas上的画笔,Paint类主要用于设置绘制风格,包括画笔颜色.画笔粗细.填充风格等. 7.2

疯狂Android讲义 - 学习笔记(八)

第10章 Service与BroadcastReceiver 10.1 Service简介 Service组件也是可执行的程序,有自己的生命周期,创建.配置Service与创建.配置Activity的过程基本相似.Service一直在后台运行,没有用户界面. 10.1.1 创建.配置Service 需要2个步骤:1 定义基础Service的子类,2 在AndroidManifest.xml文件中配置Service. Service与Activity都是从Context派生出来的,因此都可以调用C

疯狂Android讲义 - 学习笔记(五)

第五章 Android使用统一的Intent对象来封装“启动意图”,不管是启动Activity.Service组件.或者BroadcastReceiver等,提供了一致的编程模型.Intent设计有点类似于Struts2框架中的逻辑视图设计. Intent还是应用程序组件之间通信的重要媒介:数据封装成Bundle对象,Intent携带Bundle对象. 5.1 Intent对象详解 5.2 Intent的属性及intent-filter配置 5.2.1 Component属性 5.2.2 Act

疯狂Android讲义 - 学习笔记(四)

Android应用通常有多个Activity,多个Activity组成Activity栈,当前活动的Activity位于栈顶.Activity相当于Java Web开发的Servlet.当Activity处于Android应用运行时,同样受系统控制.有生命周期. 4.1 建立.配置和使用Activity 4.1.1 Activity 建立自己的Activity需要集成Activity基类,在不同的应用场景,有时也能集成Activity的子类. Activity间接或直接继承了Context.Co

疯狂Android讲义 - 学习笔记(七)

第8章 Android数据存储与IO  Java IO的数据存储可以移植到Android应用开发上来,Android系统还提供了一些专门的IO API. Android系统内置了SQLite数据库,SQLite是轻量级的,没有后台进程,整个数据库对应一个文件,这样可以非常方便的在不同设备之间移植.Android为访问SQLite提供了大量便捷的API. 8.1 使用SharedPreferences 适用于保存简单格式的数据. 8.1.1 SharedPreferences 与 Editor S

【疯狂Java讲义学习笔记】【数据类型与运算符】

[学习笔记]1.8bit = 1byte,4byte = 1word.Java中的整型数据有byte(1字节),short(2字节),int(4字节),long(8字节).Java中的浮点数据有float(4字节),double(8字节)Java中还有一个字符型char(2字节),本质也是整型Java中的布尔型boolean(1位) 2.类型转换分为自动类型转换和强制类型转换.自动类型转换,比如:范围小的数赋值给了范围大的数:空字符串和基本类型数值连接. 3.表达式类型的自动提升:当一个算术表达

【疯狂Java讲义学习笔记】【流程控制与数组】

[学习笔记]1.switch语句后的expression表达式的数据类型只能是byte.short.char.int四个整数类型.String(Java 7后才支持)和枚举类型. 2.数组的长度不可变,定义数组时候不能指定数组的长度.为数组分配空间的时候一定要进行初始化,数组初始化的方法有两种,第一种是静态初始化,在数组中直接为每个数组元素赋上初值,另一种是动态初始化,在初始化的时候指定数组的长度,由系统来为每个元素指定初值.注意的是两种初始化不能够同时使用,即既指定数组的长度,同时又为每个元素

疯狂Android讲义 - 学习笔记(三)

Android的事件处理 3.1 Android提供了两套事件处理机制:基于监听的事件处理.基于回调的事件处理. 3.2 基于监听的事件处理 3.2.1 监听的处理模型  主要涉及三类对象:EventSource.Event.EventListener. Android的事件处理机制是一种委派式(Delegation)事件处理方式:普通组件将整个事件处理委托给特定的对象(事件监听器),可以把所有可能的事件授权给不同的事件监听器来处理,也可以让一类事件都使用同一个事件监听器来处理. 事件监听类是一

《疯狂XML讲义》学习笔记

<疯狂XML讲义>主要分为五个部分.第一部分介绍了XML.DTD.XML Schema等基础知识,这些知识主要教读者如何定义有效的XML文档,这部分 内容是深入学习后面知识的基础,也是每个使用XML的开发者都应该掌握的 基础.第二部分介绍了CSS.XSLT和XPath等知识,通过使用CSS或XSLT,可 直接将XML文档当成视图技术.第三部分介绍了DOM.SAX.JAXP.dom4j. JDOM.XQuery和XQJ等,其中的DOM.SAX.JAXP.dom4j和JDOM都以结构化的 方式来创