《Effective Java》学习笔记1(2014.3.30)

来源:互联网 发布:firewall cmd关闭端口 编辑:程序博客网 时间:2024/06/06 05:31

       今天看了《Effective Java》的第2章和第3章,12条知识只是懂了第2条和第5条。尼玛,是太难了还是我太笨了,也不能这么打击人吧。算了,懂多少知识是多少,先记录下来,便于以后复习。不懂的以后再慢慢搞会吧!!

知识点1:类获取本身实例不仅可以通过提供一个公有构造器,还可以通过静态工厂方法。静态工厂方法优势有二。一为有名称,易于阅读。二为不必在每次调用时都创建一个新的对象。------《第1条:考虑用静态方法代替构造器》

知识点2:遇到多个构造器参数时考虑用构建器。当一个类有多个参数时,编写类有3个方法。一为重叠构造器模式,二为JavaBeans模式,三为Builder模式。那么对于重叠构造器 模式而言,只是适宜于参数数目不多的情况,因为需要重写多个构造方法,而且在创建初始化实例时不便于阅读,容易出错;对于JavaBeans模式,即先调用一个无参构造器创建对象,然后调用setter方法设置每个必要的参数,这种方式缺点为需要程序员付出额外的努力来确保它的线程安全(我也不知道为什么);对于Builder模式,则是比较好的,它结合了以上两种的优点,既便于阅读,而且能够保证安全。它先不直接生成想要的对象,而是先生成Builder对象,再调用类似于setter的方法来设置每个可选参数。例如代码:

public class NutritionFacts {private final int servingSize;private final int servings;private final int calories;private final int fat;private final int sodium;private final int carbohydrate;public static class Builder{//Required parametersprivate final int servingSize;private final int servings;//Optional parameters - initialized to default valuesprivate int calories = 0;private int fat = 0;private int carbohydrate = 0;private int sodium = 0;public Builder(int servingSize,int servings){this.servingSize = servingSize;this.servings = servings;}public Builder calories(int val){calories = val;return this;}public Builder fat(int val){fat = val;return this;}public Builder carbohydrate(int val){carbohydrate = val;return this;}public Builder sodium(int val){sodium = val;return this;}public NutritionFacts build(){return new NutritionFacts(this);}}private NutritionFacts(Builder builder){servingSize = builder.servingSize;servings = builder.servings;calories = builder.calories;fat = builder.fat;sodium = builder.sodium;carbohydrate = builder.carbohydrate;}public void print(){System.out.println("servingSize = " + servingSize +"\nservings = " + servings + "\ncalories = " + calories +"\nfat = " + fat + "\nsodium = " + sodium +"\ncarbohydrate = " + carbohydrate);}}
在主函数中:

public class Test {public static void main(String args[]){NutritionFacts cocaCola = new NutritionFacts.Builder(240, 8).calories(100).sodium(35).carbohydrate(27).build();cocaCola.print();}}
就可以输出:

servingSize = 240
servings = 8
calories = 100
fat = 0
sodium = 35
carbohydrate = 27   ------《第2条:遇到多个构造器参数时要考虑用构建器》


知识点3:通过私有构造器强化不可实例化的能力。企图将类做成抽象类来强化该类不可被实例化,这是行不通的,因为这样可以会误导别人是为了继承而设计的。要强化该类不可被实例化,可以把这个类包含私有构造器。 ------《第4条:通过私有构造器强化不可实例化的能力》

知识点4:避免创建不必要的对象。如果对象不可变,理论上应该要得以重用,已知不会被修改的可变对象,也应该被重用。例如:

String s = new String("abc");
String s = "abc";
区别:传递给String构造器参数“abc”本身就是一个String实例,所以不用像第一个那样再次创建一个实例。这样每执行一次,第一个就要多创建一个String对象。再比如:

检验一个人是否1946年至1965年之间出生,可以由以下两段不同的代码:

package Person;import java.util.Calendar;import java.util.Date;import java.util.TimeZone;public class Person {private final Date birthDate;Person(Date val){birthDate = val;}public boolean isBabyBoomer(){Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));gmtCal.set(1946,Calendar.JANUARY,1,0,0,0);Date boomStart = gmtCal.getTime();gmtCal.set(1965,Calendar.JANUARY,1,0,0,0);Date boomEnd = gmtCal.getTime();return birthDate.compareTo(boomStart) >= 0 && birthDate.compareTo(boomEnd) < 0;}}

package Person;import java.util.Calendar;import java.util.Date;import java.util.TimeZone;public class Person1 {private final Date birthDate;private static final Date BOOM_START;private static final Date BOOM_END;Person1(Date val){birthDate = val;}static{Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));gmtCal.set(1946,Calendar.JANUARY,1,0,0,0);BOOM_START = gmtCal.getTime();gmtCal.set(1965,Calendar.JANUARY,1,0,0,0);BOOM_END = gmtCal.getTime();}public boolean isBabyBoomer(){return birthDate.compareTo(BOOM_START) >= 0 &&birthDate.compareTo(BOOM_END) < 0;}}

代码2的好处是:在代码1中,每调用一次isBabyBoomer方法,就要创建一个Calendar,两个Date实例一次,而实际上不需要这样,理论上只需要创建一次。这样便能提高性能,final的使用也使得代码更加的便于理解

PS:也可以延迟初始化,在第一次调用的时候才创建,但不建议这么做,因为这会使方法的实现更为复杂(我也不知道为什么)。------《第5条:避免创建不必要的对象》


知识点5:避免使用终结方法。终结方法的缺点在于不能保证会被及时地执行,从一个对象变得不可到达开始,到它的终结方法被执行,所花费的时候是任意的。所以注重时间的任务不应该用终结方法完成。另外,终结方法也不能保证会被执行。当确实需要终结时,可以提供一个显示的终止方法,如close,cancel方法等。------《第7条:避免使用终结方法》


总结:尚未清楚且需进一步掌握的:

1.关于栈的知识(第6条涉及到)。

2.在类里面在定义类的知识(第2条知识,也是基础知识不过关啊,满眼的泪~~)

3.枚举类型的知识(第3条提到)

4.object对象的知识(这个直接导致第3章一章都不懂~~)


0 0