Effective Java学习记录(1)

前阵子翻了翻《Effective Java》这本书,觉得里面的内容不错,觉得有必要留下些笔记以供以后自己翻看。</span>

本书比较老了,大概总结了jdk1.6及以前版本编程的78条原则,大多数到现在也比较适用。


一、创建和销毁对象

1、考虑用静态工厂方法代替构造器

对于类而言,为了让客户端获得其自身的一个实例,最常用的方法是使用一个公有的构造函数创建一个对象。如下列构造函数:

 new BigInteger(int, int, Random);
该构造函数是用于创建一个随机素数,但显然这个构造器并不能很好的表达这个含义,所以我们最好用下面的方法。

BigInteger.probablePrime(int,Ramdom)
在jdk1.4时已经采用了该方法。

这也是静态方法对于构造函数的第一个优势:静态方法有名称,更方便用户阅读。

让我们再看一下另一个j静态工厂方法例子:

Boolean.valueOf(boolean);
Integer.valueOf(int);
该方法可以有效的避免实例重复创建,可以更好的重用实例。

这也是静态方法对于构造函数的第二个优势:不必在每次调用它们的时候都创建一个新的对象。

java1.5中引入了EnumSet,其中只定义了静态方法,是用于操作枚举。EnumSet很多方法都会调用以下的方法:

   /**
     * Creates an empty enum set with the specified element type.
     *
     * @param <E> The class of the elements in the set
     * @param elementType the class object of the element type for this enum
     *     set
     * @return An empty enum set of the specified type.
     * @throws NullPointerException if <tt>elementType</tt> is null
     */
    public static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType) {
        Enum<?>[] universe = getUniverse(elementType);
        if (universe == null)
            throw new ClassCastException(elementType + " not an enum");

        if (universe.length <= 64)
            return new RegularEnumSet<>(elementType, universe);
        else
            return new JumboEnumSet<>(elementType, universe);
    }
由该方法可以看出,当枚举数量大于64时会返回JumboEnumSet实现,反之是RegularEnumSet。

这是静态方法对于构造函数的第三个优势:可以返回原返回类型的任何子类型的对象。

在使用泛型时,经常会出现以下:

Map<String,List<String>> map=new HashMap<String,List<String>>();

但如果使用静态方法的话,代码可以更简洁。

假如HashMap中定义了以下方法:

public static <K,V> HashMap<K,V> newInstance(){
    return new HashMap<K,V>();
}
那么就可以将new改成如下的方法:

Map<String,List<String>> map=HashMap.newInstance();

这是静态方法对于构造函数的第四个优势:使用泛型创建实例时使用静态共产使代码更简洁

这种类型类型推导在1.6还没有实现,但在1.8中是可以用以下来代替:

Map<String,List<String>> map=new HashMap<>();

静态工厂方法的缺点:

1、如果类中没有提供public或protected构造方法,就不能被子类化,但现在一般提倡组合而不是继承,所以并不是问题。

2、和其他静态方法没有任何区别,一般不会在API文档中被标识出来,最好在类的java doc中有明确阐述类实例时需要调用哪个静态方法。


2、遇到多个构造器参数时要考虑使用构建器

静态工厂和构造函数有个共同的局限性,那就是都不能很好的扩展参数。

如下代码:

构造函数模式:

public class NutritionFact {

    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 NutritionFact(final int servingSize, final int servings, final int calories, final int fat, final int sodium,final int carbohydrate) {
<span style="white-space:pre">	</span>super();
<span style="white-space:pre">	</span>this.servingSize = servingSize;
<span style="white-space:pre">	</span>this.servings = servings;
<span style="white-space:pre">	</span>this.calories = calories;
<span style="white-space:pre">	</span>this.fat = fat;
<span style="white-space:pre">	</span>this.sodium = sodium;
<span style="white-space:pre">	</span>this.carbohydrate = carbohydrate;
    }

    public NutritionFact(final int servingSize, final int servings) {
<span style="white-space:pre">	</span>this(servingSize, servings, 0, 0, 0, 0);
    }

    public NutritionFact(final int servingSize, final int servings, final int calories) {
<span style="white-space:pre">	</span>this(servingSize, servings, calories, 0, 0, 0);
    }

    public NutritionFact(final int servingSize, final int servings, final int calories, final int fat) {
<span style="white-space:pre">	</span>this(servingSize, servings, calories, fat, 0, 0);
    }

    public NutritionFact(final int servingSize, final int servings, final int calories, final int fat,final int sodium) {
<span style="white-space:pre">	</span>this(servingSize, servings, calories, fat, sodium, 0);
    }
}

javabean模式:

public class NutritionFact {

    private int servingSize = -1;

    private int servings = -1;

    private int calories;

    private int fat;

    private int sodium;

    private int carbohyd
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值