写在最开头,个人认为这是java或者是软件构造里面最核心的部分。如何面对给出的要求,构造出结构清晰合理的类和接口,我觉得是最有难度的,也是最充满艺术性的。
本章小结:
数据类型:基本数据类型,对象数据类型
可变性与不可变性:可变与不可变,防御性编程
设计规约:SPEC
》》数据类型
基本数据类型和对象数据类型的区别
java中有8个封装了的对象类型表示基本类型:– Boolean, Integer, Short, Long, Character, Float, Double,Byte(尽量避免使用)
类型检测:Java是一种静态类型的语言,所有变量的类型在编译的时候就已经知道了(程序还没有运行),所以编译器也可以测出每一个表达式的类型。在动态类型语言中(例如Python),这种类型检查是发生在程序运行的时候。
——静态类型检查:可在编译阶段发现错误,避免了将错误带入到运行阶段,可提高程序正确性/健壮性
静态分析检查的类型:一般来说只检查变量的类型
——动态类型检查:倾向于检查“值”
动态分析检查的类型:
》》Mutability and Immutability(可变性和不可变性)
改变一个变量:是将该变量指向另一个值得存储空间
改变一个变量的值:是将该变量当前指向的值的存储空间中写入一个新的值
1.不变性:不变数据类型一旦被创建,其值不能改变。
——final 变量能被显式地初始化并且只能初始化一次。如果编译器不能确定final变量不会改变,就提示错误,这也是静态类型检查的一部分。注意:final类无法派生子类,final变量无法改变值/引用,final方法无法被子类重写
——基本类型及其封装对象类型都是不可变的
——不可变的引用是指一旦指定引用位置后,不可再次指定。
2.可变性:可以有方法改变对象的值
StringBuilder是一个可变类型:
String s="a"; StringBuilder sb=new StringBuilder("a");
s=s.concat("b"); sb.append("b");
3.可变和不可变的优缺点
——可变数据类型最小化的拷贝以提高效率
——使用不可变类型,对其频繁修改会产生大量的临时拷贝 (需要垃圾回收 )
——可变数据类型,可获得更好的效能;可变数据类型也适合在多个模块之间共享数据
——不可变数据类型更安全,更易于理解,也更方便改变;
》》快照图:不可变对象用双层椭圆;不可变引用(final)用双线箭头
在用final修饰可变类型的时候,引用不能变,值能变。
在用可变去引用不可变时,可能会出现预期外的结果。
》》防御式拷贝:方法返回的时候不要直接返回可变的变量,那样可能会导致变量改变。应该返回一个拷贝之后的变量(不直接引用原来的变量)
》》设计规约
——为什么要有设计规约:很多bug来自于双方之间的误解;没有规约,那么不同开发者的理解就可能不同代码惯例增加了软件包的可读性,使工程师们更快、更完整的理解软件可以帮助程序员养成良好的编程习惯,提高代码质量没有规约,难以定位错误
——使用设计规约的好处规约起到了契约的作用。代表着程序与客户端之间达成的一致;客户端无需阅读调用函数的代码,只需理解spec即可。精确的规约,有助于区分责任,给“供需双方”确定了责任,在调用的时候双方都要遵守。
行为等价性:站在客户端视角看等价性,根据规约判断功能是否等价
规约的结构:一个方法的规约常由以下几个短句组成契约:如果前置条件满足了,后置条件必须满足。如果没有满足,将产生不确定的异常行为
——前置条件(precondition):对客户端的约束,在使用方法时必须满足的条件。由关键字 requires 表示
——后置条件(postcondition):对开发者的约束,方法结束时必须满足的条件。由关键字 effects 表示
——异常行为(Exceptional behavior):如果前置条件被违背,会发生什么
方法前的注释也是一种规约,参数用@param表示,前置条件写在@param后面;后置条件写在@return和@throws(可能发生的异常)后面
尽量不要设计可变的(mutating)规约:除非后置条件声明,否则方法内部不应该改变输入参数;避免使用可变对象
》》规约的评价:有三个标准,规约的正确性、规约的陈述性、规约的强度
——规约的确定性:确定的规约是给定一个满足前置条件的输入,其输出是唯一的、明确的;欠定的规约是同一个输入可以有多个输出
——规约的陈述性:操作式规约:伪代码;声明式规约:没有内部实现的描述,只有 “初-终”状态; 声明式规约更有价值,内部实现的细节不在规约里呈现,而放在代码实现体内部注释里呈现。
——规约的强度:通过比较规约的强度来判断是否可以用一个规约替换另一个;如果规约的强度 S2>=S1,就可以用S2代替S1,体现有二:一个更强的规约包括更轻松的前置条件和更严格的后置条件;越强的规约,意味着实现者的自由度和责任越重,而客户的责任越轻。S2的前置条件更弱 || S2的后置条件更强
图表规范:某个具体实现,若满足规约则落在范围内;否则,在其之外