• 《Effective Java》读书笔记六(方法)


    No38 检查参数的有效性

    对于公有的方法,要用Javadoc的@throws标签(tag)在文档中说明违反参数值时会抛出的异常。这样的异常通常为IllegalArgumentException、IndexOutOfBoundsException或NullPointerException。

    /**
    * ...
    * @throws ArithmeticException if m is less than or equal to 0
    */
    public BigInteger mod(BigInteger m) {
             if(m.signum() <= 0)
                 throw new ArithmeticException("Modulus <=0:"+ m);
    
    ...
    //Do the computation }

    对于非公有的方法通常应该使用断言(assertion)来检查它们的参数:

    // private helper function for a recursive sort
    private static void sort(long a[], int offset, int length){
        assert a != null;
        assert offset >=0 && offset <= a.length;
        assert length >= 0&& length <= a.length – offset;
    
        ...// Do the computation
    }

    断言如果失败,将会抛出AssertionError。

    No39 必须时进行保护性拷贝

    有经验的程序员通常使用Date.getTime()返回的long基本类型作为内部的时间表示法,而不是使用Date对象引用。主要是因为Date是可变的,它可能被外界调用无意中更改掉而失去它的真实意义。

    No40 谨慎设计方法签名

    • 避免过长的参数列表,相同类型的长参数序列格外有害。
    • 对于参数类型,要优先使用接口而不是类。

        比如:

    // 不合适的方法定义
    private void sort(HashMap<String> hashMap); 
    
    // 合适的方法定义
    // 这使你可以传入一个Hashtable、HashMap、TreeMap等等。更改起来很容易。
    private void sort(Map<String> map); 

    No41 慎用重载

    下面这个程序的意图是很好的,它试图根据一个集合(collection)是Set、List,还是其他的集合类型来对它进行分类:

    // Broken! - What does this program print?
    import java.util.*;
    import java.math.*;
    
    public class CollectionClassifier {
        public static String classify(Set<?> s) {
            return "Set";
        }
    
        public static String classify(List<?> lst) {
            return "List";
        }
    
        public static String classify(Collection<?> c) {
            return "Unknown Collection";
        }
    
        public static void main(String[] args) {
            Collection<?>[] collections = {
                new HashSet<String>(),
                new ArrayList<BigInteger>(),
                new HashMap<String, String>().values()
            };
    
            for (Collection<?> c : collections)
                System.out.println(classify(c));
        }
    }

    你可能期望这个程序会打印出“Set”,紧接着是“List”,以及“Unknown Collection”,但实际上不是这样,它是打印“Unknown Collection”三次。

    这个程序的行为有悖于常理,因为对于重载方法(overloaded method)的选择是静态的;而对于被覆盖的方法(overridded method)的选择则是静态的。

    另外还是注意,在集合的操作中,remove(i)与remove((Integer)i)的含义是不一样的。聪明的你一定知道区别在哪儿了。

    No43 返回零长度的数组或者集合,而不是null

    像下面的方法:

    private final List<Cheese> cheeseInStock = ...;
    
    /**
    *@return an array containing all of the cheeses in the shop.
    * or null if no cheese are available for purchase.
    */
    public Cheese[]  getCheeses() {
             if(cheeseInStock.size() == 0)
                    return null;
             ...
    }

    把没有奶酪(cheese)可买的情况当作是一种特例,这是不全常理的。这样做会要求客户端中必须有额外的代码来处理null返回值。例如:

    Cheese[] cheeses = shop.getCheeses();
    if(cheeses != null && Arrays.asList(cheeses).contains(Cheese.STILTON))
         System.out.println(“Jolly good, just the thing.”);

    而不是下面这段代码:

    if(Arrays.asList(shop.getCheeses()).contains(Cheese.STILTON))
         System.out.println(“Jolly good, just the thing.”);
  • 相关阅读:
    04-Bootstrap的插件
    03-Bootstrap学习
    02-移动端单位介绍
    01 响应式页面-@media介绍,
    14-jQuery补充
    13-jQuery的ajax
    12-事件委托(事件代理)
    11-jQuery的事件绑定和解绑
    10-事件对象
    09-JS的事件流的概念(重点)
  • 原文地址:https://www.cnblogs.com/nayitian/p/3250023.html
Copyright © 2020-2023  润新知