首页 > 代码库 > 第七章:方法。ITEM39:必要时进行保护性拷贝。

第七章:方法。ITEM39:必要时进行保护性拷贝。

 1 package com.twoslow.cha7; 2  3 import java.util.Date; 4  5 public final class Period { 6  7     private final Date start ;  8     private final Date end ;  9     10     public Period(Date start , Date end) {11         if(start.compareTo(end) > 0)12             throw new IllegalArgumentException(start +" after " +end) ;13         this.start = start ; 14         this.end = end ; 15     }16     17     public Date start() {18         return start ; 19     }20     21     public Date end() {22         return end ; 23     }24     25     26     @Override27     public String toString() {28         return "Period [start=" + start + ", end=" + end + "]";29     }30 31     public static void main(String[] args) {32         Date start = new Date() ; 33         Date end = new Date() ;34         Period p = new Period(start, end) ;35         System.out.println(p);36         end.setYear(98);//改变了内部end对象37         System.out.println(p);38     }39 }
 1     public Period(Date start , Date end) { 2 //        if(start.compareTo(end) > 0) 3 //            throw new IllegalArgumentException(start +" after " +end) ; 4 //        this.start = start ;  5 //        this.end = end ;  6         /* 7          * 保护性拷贝是在检查参数的有效性之前进行的,并且有效性是针对拷贝之后的对象,而不是针对原始的对象。 8          * 没有使用clone方法,因为Date是非final的,不能保证clone方法一定返回类为java.util.Date的对象。 9          */10         this.start = new Date(start.getTime()) ;11         this.end = new Date(end.getTime()) ;12         if(start.compareTo(end) > 0)13             throw new IllegalArgumentException(start +" after " +end) ;14     }15     16     public Date start() {17         return new Date(start.getTime()) ; 18     }19     20     public Date end() {21         return new Date(end.getTime()) ; 22     }

PS:长度非0的数组总是可变的。 在把内部数组返回给客户端之前,应该总要进行保护性拷贝。另一种方案是,给客户端返回该数组的不可变视图。见:http://www.cnblogs.com/twoslow/p/3937657.html

第七章:方法。ITEM39:必要时进行保护性拷贝。