Java经典的书籍有几本,都是很多有经验的开发人员推荐的,包括Java编程思想,深入理解Java虚拟机,Java核心技术和Effective Java。工作之后发现自己读的技术书籍少的可怜,因为不爱读书,很多基础的知识都忘了。从最近开始,打算好好的看书,把这些经典的书籍好好的看一遍,把重要的内容记下来。以下是Effective Java的读书笔记:
第一章 引言
这本书讲解了78个条目的,每个条目讨论一条规则,从第二章开始讲解。
第二章 创建和销毁对象
第1条: 考虑用静态工厂方法代替构造器
优点:1. 与构造器不同的第一大优势在于,它们有名称;
2. 与构造器不同的第二大优势在于,不必在每次调用它们的时候都创建一个新对象;
3. 与构造器不同的第三大优势在于,它们可以返回原返回类型的任何子类型的对象;
4. 在创建参数化类型实例的时候,它们使代码变得更加简洁
缺点:1. 类如果不含公有的或受保护的构造器,就不能被子类化
2. 它们与其他的静态方法实际上没有任何区别
例子如下:
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class Services {
private Services(){
}
private static final Map providers =
new ConcurrentHashMap();
public static final String DEFAULT_PROVIDER_NAME = "";
public static void registerDefaultProvider(Provider p){
registerProvider(DEFAULT_PROVIDER_NAME ,p);
}
public static void registerProvider(String name, Provider p){
providers.put(name, p);
}
public static Service newInstance(){
return newInstance(DEFAULT_PROVIDER_NAME);
}
public static Service newInstance(String name){
Provider p = providers.get(name);
if(p == null){
throw new IllegalArgumentException(
No provider registered with name: + name);
}
return p.newService();
}
}
如下是几种方法来创建类的对象
重叠构造器模式
例子如下
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 NutritionFacts(int servingSize, int servings) {
this(servingSize, servings, 0);
}
public NutritionFacts(int servingSize, int servings, int calories) {
this(servingSize, servings, calories, 0);
}
public NutritionFacts(int servingSize, int servings, int calories, int fat) {
this(servingSize, servings, calories, fat, 0);
}
public NutritionFacts(int servingSize, int servings, int calories, int fat,
int sodium) {
this(servingSize, servings, calories, fat, sodium, 0);
}
public NutritionFacts(int servingSize, int servings, int calories, int fat,
int sodium, int carbohydrate) {
this.servingSize = servingSize;
this.servings = servings;
this.calories = calories;
this.fat = fat;
this.sodium = sodium;
this.carbohydrate = carbohydrate;
}
}
JavaBean模式
例子如下:
public class NutritionFacts {
private int servingSize = -1;
private int servings = -1;
private int calories = 0;
private int fat = 0;
private int sodium = 0;
private int carbohydrate = 0;
public NutritionFacts() {
}
public void setServingSize(int servingSize) {
this.servingSize = servingSize;
}
public void setServings(int servings) {
this.servings = servings;
}
public void setCalories(int calories) {
this.calories = calories;
}
public void setFat(int fat) {
this.fat = fat;
}
public void setSodium(int sodium) {
this.sodium = sodium;
}
public void setCarbohydrate(int carbohydrate) {
this.carbohydrate = carbohydrate;
}
}
例子如下:
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{
private final int servingSize;
private final int servings;
private 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;
}
}
比重叠构造器模式比,它的客户端代码将更易于阅读和编写
比JavaBean更加安全
第3条: 用私有构造器或者枚举类型强化Singleton属性
单例模式的2种用法(jdk1.5之前)
1. 公有静态成员是final域
public class Elvis {
public static final Elvis INSTANCE = new Elvis();
private Elvis(){
}
public void leaveTheBuilding(){
}
}
public class Elvis {
private static final Elvis INSTANCE = new Elvis();
private Elvis(){
}
public static Elvis getInstance(){
return INSTANCE;
}
public void leaveTheBuilding(){
}
}
enum Elvis {
INSTANCE;
public void leaveTheBuilding(){
System.out.println("leaveTheBuilding......");
}
}
public class A{
public void get(){
Elvis.INSTANCE.leaveTheBuilding();
}
public static void main(String[] args){
A a = new A();
a.get();
}
}
编写只包含静态方法和静态域的类,这样的类要求不能被实例化,这时候就可以通过把构造器定义为私有类型就可以了,(Java里的一些工具类不希望被实例化)
public class UtilityClass {
private UtilityClass(){
throw new AssertionError();
}
}
AssertionError是为了防止类内部调用构造器。