第七章:方法。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     @Override
27     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

时间: 2024-10-10 01:03:16

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

[Effective Java]第七章 方法

第七章      方法 38.      检查参数的有效性 绝大多数方法和构造器对于传递给它们的参数值都会有某些限制.例如,索引值必须是非负的,对象引用不能为null等,这些都是常见的.你应该在文档中清楚地指明所有这些限制,并且在方法体的开头处检查参数,以强制施加这些限制. 应该在方法和构造器体前进行了参数的有效性检查,并且及时向外抛出适当的异常.如果方法没有检查它的参数,就有可能发生几种情形.该方法可能在处理过程中失败,并且产生令人费解的异常,更有可能,该方法可以正常返回,但是会悄悄地计算出错

第三十九条:必要时进行保护性拷贝

使Java使用起来如此舒适的一个因素在于,它是一门安全的语言.这意味着,它对于缓冲区溢出,数组越界,非法指针以及其他的内存破坏 都自动免疫,而这些错误却困扰着诸如C和C++这样的不安全语言.在一门安全的语言中,在设计类的时候,可以确切的知道,无论系统的 其他部分发生什么事情,这些类的约束都可以保持为真.对于那些"把所有的内存当成一个巨大的数组来看待"的语言来说,这是不可能的. 有一种情况进行保护性拷贝就是需要的: public  class   Period { private   f

第39条:必要时进行保护性拷贝

Java是一门安全的语言,但是如果不采取措施,还是无法保证安全性.假设类的客户端会尽其所能来破坏类的约束条件,因此必须保护性地设计程序. 考虑下面的类,声称表示一段不可变的时间周期: import java.util.Date; public final class Period { private final Date start; private final Date end; public Period(Date start, Date end) { if(start.compareTo(

必要时进行保护性拷贝

假设类的客户端会尽其所能来破坏这个类的约束条件,因此你必须保护性的设计程序.demo: 1 import java.util.Date; 2 3 public final class Period { 4 private final Date start; 5 private final Date end; 6 public Period(Date start,Date end) { 7 if(start.compareTo(end) > 0){ 8 throw new IllegalArgum

第七章 方法

方法名可以由英文字母.数字.下划线组成,但是不能以数字开头. 对象.方法名(参数1,参数2,…,参数n) 调用方法时,不管后面参数多少个,方法调用的括号都可以不写,参数个数多时推荐写上 但是定义方法时: 使用do~end时,可以省略把参数列表括起来的() 使用{}时,只有在没有参数的时候才可以省略把参数列表括起来的(),有一个以上的参数就不能省略 (1)Ruby中有些方法看起来很像运算符,如数组或散列下标的[],+,-等都是方法 在用方法实现的运算符中,有的可以重新定义,有的不行,见第九章 (2

《Effective Java》第7章 方法

第38条:检查参数的有效性 对于公有的方法,要用javadoc的@throws标签(tag)在文档中说明违反参数值限制时会抛出的异常.这样的异常通常为IllegalArgumentException, IndexOutOfBoundsException或NullPointerException. 非公有的方法通常应该使用断言(assertion)来检查它们的参数,具体做法如下所示: 第39条:必要时进行保护性拷贝 没有对象的帮助时,虽然另个类不可能修改对象的内部状态,但是对象很容易在无意识的情况

《Effective Java 2nd》第7章 方法

目录 第38条 检查参数的有效性 第39条 必要时进行保护性拷贝 第40条 谨慎设计方法签名 第41条 慎用重载 第42条 慎用可变参数 第43条 返回零长度的数组或集合,而不是null 第44条 为所有导出的API元素编写文档注释 关注点:可用性.健壮性.灵活性 第38条 检查参数的有效性 在编写方法或者构造器的时候,应该考虑参数有哪些限制,并显式检查 第39条 必要时进行保护性拷贝 如果类具有从客户端得到或者返回到客户端的可变组件,为了维持不可变性,必要时进行保护性拷贝. 否则,在文档中写明

C++_第七章函数的基本知识_求阶乘的子函数_ 函数参数类型为数组_ 求数组内所有元素和、部分元素和的方法_实现了先从键盘输入到一个数组中,再用for循环取读出数组中的元素 for循环也可以用break来结束循环的

/* 第七章函数的基本知识 */ /*01)c++对于返回值有一定的限制:可以是常量.变量.指针.结构对象或表达式,但不可以是数组02)c++返回数组的方法:将数组作为结构会对象组成部分来返回03)函数遇到return则结束该函数04)如果一个函数的两房额参数类型相同,则必须分别制定每个参数的类型,而不能像声明常规变量那样,将声明组合在一起05)*/ //本代码注意double类型的写法以及double和int类型数据的转换 1 #include <iostream> 2 3 void che

软件工程——理论、方法与实践 第七章

第七章 需求分析阶段的核心是产生一个准确的.完整的.一致的和可验证的系统模型,称为分析模型.主要讲 1.分析的概念:分析类和分析活动,类包括边界类.控制类和实体类. 2.识别分析类:通常需要充分理解系统内部的行为,分为识别边界类.控制类.实体类. 3.定义交互行为,讲了顺序图可以将用例和分析对象联系在一起,还有顺序图的绘制步骤. 4.建立分析类图:在分析了对象之间的交互行为之后,开发人员需要建立分析类图,即定义分析类之间的关系和分析类的属性,以MiniLibrary系统为例讲解了实体类之间的关系