第四章Data Type and Type Checking 数据类型与类型检验
1.Data type in programming languages
(1)数据类型:一组值以及可以对其进行的操作。
(2)Java中的数据类型分为基本数据类型和对象数据类型
基本数据类型以小写字母开头,对象数据类型以大写字母开头
(3)对象数据类型的层次关系
所有的对象数据类型(除了Object)都有一个父类,以extends声明
例如:class Basketball extends Sports{...}
子类对父类的继承:1.继承可见的类型和方法2.可以重写方法(override)
(4)Boxed primitives 将基本数据类型包装为对象数据类型
通常用于定义容器类型时,因为容器类型操作要求对象数据类型,所以需要对基本数据类型包装,使其成为对象数据类型,一般情况下会自动转换
例如:list.add(1);等价于list.add(Integer.valueOf(1));
(5)操作符
方法、函数
2.Static vs. dynamic data type checkin
(1)静态类型语言(例如:Java):所有变量的类型在编译时已知,因此编译器可以推导表达式类型在编译阶段进行类型检查
(2)动态类型语言(例如:Python):在运行阶段进行检查
(3)静态检查(对于类型的检查,不考虑值):在程序运行前自动找到bug
动态类型语言也可以进行静态检查,如Python,只不过无法检查类型,但可以检查语法错误。
静态检查可以在编译阶段发现错误,避免了将错误带入到运行阶段,可提高程序正确性/健壮性。
检查语法错误,类名/函数名错误,参数数目错误,参数类型错误,返回值类型错误。
(4)动态检查(对于值的检查):在程序执行的时候自动找到bug
检查非法的参数值,非法的返回值,越界,空指针
(5)一些检查不出来的错误:
整数的除法,整数的溢出,NaN
double sum=7;double n=0;double average=sum/n;属于检查不出来的错误,wrong anser,因为double中0是一个近似值。
3.Mutability & Immutability
(1)
改变一个变量:将该变量指向另一个存储空间
改变一个变量的值:将该变量当前指向的存储空间中写入一个新的值
(2)
不变性:重要设计原则
不变数据类型:一旦被创建,其值不能改变
如果是引用数据类型,也可以是不变的:一旦确定其所指向的对象,不能再改变指向其他对象。
不变对象:一旦被创建,始终指向同一个值/引用
可变对象:拥有方法可以修改自己的值/引用
final:
final int n=5;
final Person a= new Person(“lth”);
编译器进行static checking时,如判断final 变量首次赋值后发生了改变
尽量使用final变量作为方法的输入参数,作为局部变量。
final类无法派生子类
final变量无法改变值/引用
final方法无法被子类重写
- String是不可变类型,StringBuilder是可变数据类型。
只有一个引用,没有区别。有多个引用的时候,差异就出现了。
(4)
使用不可变类型,对其频繁修改会产生大量的临时拷贝(需要垃圾回收)
可变类型可以获得更好的性能,也适合在多个模块中共享数据。
不可变类型更安全,在其他质量指标上表现更好
(5)防御式拷贝:返回一个全新的对象。不可变类型不需要防御式拷贝。
4.Snapshot diagram(用于描述程序运行时的内部状态)
基本数据类型 箭头
对象数据类型 可变 单线椭圆
不可变 双线椭圆
final:不可变的引用 双线箭头
5.Complex data types: Arrays and Collections
(1)
List,Set,Map
当添加一个item时,编译器会执行静态检查,确定只添加合适类型的item。
(2)迭代器
Eg.List<String> lst=...;
Iterator iter=lst.iterator();
6.Useful immutable types
(1)基本类型及其封装对象类型都是不可变的
(2)List,Set,Map都是可变的
Collections.unmodifiableList
Collections.unmodifiableSet
Collections.unmodifiableMap
这种包装器得到的结果是不可变的,只能看
但是这种不可变是在运行阶段获得的,编译阶段无法据此进行检查