软件构造笔记 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很不明确。



猜你喜欢

转载自blog.csdn.net/Goerwa/article/details/80783630
今日推荐