天天看點

《Core Java 2》讀書筆記(二)

1,防禦性程式設計。必要時應當考慮采取保護性拷貝的手段來保護内部的私有資料,先來看下面這個例子:

複制代碼

pubic final class Period

{

    private final Date start;

    private final Date end;

    public Period(Date start, Date end)

    {

        if (start.compareTo(end) > 0)

            throw new IllegalArgumentException(start + "after " + end);

        this.start = start;

        this.end = end;

    }

    public Date getStart()

        return start;

    public Date getEnd()

        return end;

}

這個類存在兩個不安全的地方,首先來看第一個攻擊代碼

Date start = new Date();

Date end = new Date();

Period p = new Period(start, end);

end.setYear(78);//改變p的内部資料!

這是因為外部和内部引用了同樣的資料,為了解決這個問題,應當修改Period的構造函數:

public Period(Date start, Date end)

    this.start = new Date(start.getTime());

    this.end = new Date(end.getTime());

    if (start.compareTo(end) > 0)

        throw new IllegalArgumentException(start + "after " + end);

這樣内部的私有資料就與外部對象指向不同,則不會被外部改變

再來看第二個攻擊代碼:

p.getEnd().setYear(78);//改變p的内部資料!

這很顯然是由于公有方法暴露了内部私有資料,我們可以隻傳回内部私有資料的隻讀版本(即其一份拷貝)

public Date getStart()

    return (Date)start.clone();

public Date getEnd()

    return (Date)end.clone();

2,讀到上面這個例子,我想起來了下面這樣的代碼片段

public class Suit

    private final String name;

    private static int nextOrdinal = 0;

    private final int ordinal = nextOrdinal++;

    private Suit(String name)

        this.name = name;

    public String toString()

        return name;

    public int compareTo(Object o)

        return o

    public static final Suit CLUBS = new Suit("Clubs");

    public static final Suit DIAMONDS = new Suit("diamonds");

    public static final Suit HEARTS = new Suit("hearts");

    public static final Suit SPADES = new Suit("spades");

    private static final Suit[] PRIVATE_VALUES = {CLUBS,DIAMONDS,HEARTS,SPADES};

    public static final List VALUES = Collections.unmodifiedList(Arrays.asList(PRIVATE_VALUES));

本文轉自Phinecos(洞庭散人)部落格園部落格,原文連結:http://www.cnblogs.com/phinecos/archive/2009/09/28/1575645.html,如需轉載請自行聯系原作者