软件构造笔记 3.1 Data Type and Type Checking
1.数据类型
变量:用特定数据类型定义,可存储满足类型约束的值。
基本数据类型(primitive type):如int、long、double
对象数据类型(object type):如String、BIgInteger
对象类型间会形成层次结构
根节点是Object,所有类都有父节点,除了Object,省略extends语句,那么默认该类父类为Object。类是其所有超类的一个实例,即继承关系:从其超类继承可见的字段和方法;可以覆盖方法来改变他们的行为。
基本类型都具有包装的对象类型,在定义集合类型时,只能使用对象类型,可自动转换,但一般情况下应避免使用对象类型。
重载可以使得同样的操作名用于不同的数据类型。
2.静态/动态类型
静态类型语言在编译阶段进行检查。
动态类型语言在运行阶段进行检查。
类型转换
静态类型检查:该错误是在程序运行之前自动发现的。可在编译阶段发现错误,避 免了将错误带入到运行阶段,可提高程序正确性/健壮性。
包含:语法错误;类名/函数名错误;参数数目错误;参数类型错误;返回类型错误。
动态类型检查:当代码出现错误时,错误会自动找到。
包含:非法的参数值;非法返回值;越界;空指针等情况。
静态类型检查 > 动态类型检查 > 无检查
3.可变/不变的数据类型
改变一个变量和改变一个变量的值是有区别的
改变一个变量:将该变量指向另一个值的存储空间。
改变一个变量的值:将该变量当前指向的值的存储空间中写入一个新的值。
不变性是重要的设计原则。不变数据类型一旦被创建,其值不能够被改变。如果是引用类型,那么确定指向的对象也是不能被改变的。
如果编译器无法确定final变量不会改变,就提示错误,这也是静态类型检查的一部分。所以,尽量使用final变量作为方法的输入参数、作为局部变量。
final的作用
Final类:不能派生子类。
final变量:不能改变值/引用。
final方法:无法被子类重写。
不变对象:一旦被创建,始终指向同一个值/引用
可变对象:拥有方法可以修改自己的值/引用
String是一个不可变类型,再被创建之后,一直具有相同的值,当使用add操作在尾部加入新的值,相当于创建了一个新的String对象。
StringBuilder是可变类型,它具有改变、删除值的方法,所以修改时不用创建新的对象。
当只有一个运用时,可变与不可变类型的差别不明显,但存在多个引用时,差别就明显了。
使用不可变类型,对其频繁的修改会产生大量需要垃圾回收的临时拷贝,而可变类型最小化拷贝以提高效率。所有使用可变类型可以获得更好的性能,也适用于在多个模块间共享数据。但是不可变数据类型更“安全”,在很多质量指标上的表现也更好。那么,我们需要考虑自己看重的指标,选择类型。
4.可变数据类型的危险性
从上述代码可看出可变类型存在的隐患:sumAbsolute函数修改了输入参数的值。
上述代码在获取partyDate后将其值+1,修改了原值,那么再再次获取其值时会发生错误。
为了解决该错误,我们可以使用防御式拷贝,即给客户端返回一个全新的Date对象,但是该拷贝在大部分时间不会被客户使用,那么使用不可变类型便可以节省频繁复制的代价。
但可变类型在作为局部变量和只有一个引用的情况下是安全的。
不变数据类型的优越性
用快照图理解数据类型
表示基本类型:
表示对象类型:
表示不可变对象:
表示不可变引用:
5.使用Arrays和Collections来处理复杂的数据类型
List是一个接口,其中的元素必须是一个对象,具体实现有ArrayList,LinkedList。
Set是一个抽象接口,是一个无序的集合,其中的元素最多出现一次。Map也是一个抽象接口。
对于Java集合,我们可以限制集合中包含的对象的类型。当我们添加一个项目时,编译器可以执行静态检查,以确保我们只添加适当类型的项目。然后,当我们拿出一件物品时,我们保证它的类型是我们所期望的。
迭代器(Iterator):用于遍历元素集合的每一个元素,主要方式有 next()返回集合中的下一个元素---这是一个增变器;hasNext()测试迭代器是否已到达集合的末尾。
迭代过程中使用collection的remove方法可能产生破坏,所有使用迭代器的remove方法。
6.不可变类型
基本类型及其封装对象类型都是不可变的,List、Set、Map的具体实现都是可变的。这些集合都有不可变类型,但是这种“不可变”是在运行阶段获得的,编译阶段无法据此进行静态检查。
7.了解空引用的危害并避免它
基本类型不能初始化为null,非基础类型可以赋值为null,但在运行时可能抛出NullPointerExceptions异常。注意null不同于“”字符串和空数组。 不小心使用null会导致各种各样的错误。另外,null很不明确。