HIT软件构造:数据类型与类型检验

目录

1.在编程语言中的数据类型

1.1基本数据类型

1.2对象数据类型

1.3对象类型形成层次结构 

2.Static vs. dynamic data type checking(静态与动态数据类型检查)

2.1Static checking

2.2Dynamic checking

2.3Static vs. Dynamic Checking

3.Mutability and Immutability

3.1Immutability 不变性

3.2Mutability and Immutability

3.3Advantage and Disadvantage of mutable types

3.4如何修改代码

4.Snapshot diagramas a code-level, run-time, and moment view

4.1Primitive and Object values in Snapshot Diagram

4.2Unreassignable/Immutable references ( final )

5.Useful immutable types


1.在编程语言中的数据类型

1.1基本数据类型

例如:
int (for integers like 5 and -200, but limited to the range ± 2^31, or roughly ± 2 billion)
long (for larger integers up to ± 2^63)
boolean (for true or false)
double (for floating-point numbers, which represent a subset of the real numbers)
char (for single characters like 'A' and '$' )

1.2对象数据类型

例如:
String represents a sequence of characters.
BigInteger represents an integer of arbitrary size.

根据Java约定,基本数据类型为小写,而对象数据类型以大写字母开头。

1.3对象类型形成层次结构 

除“object”外的所有类都有一个父类,并使用extends指定;

如果省略了extends,则默认其父类为“object”;
一个类是其所有父类的一个实例。


 

2.Static vs. dynamic data type checking(静态与动态数据类型检查)

2.1Static checking

静态类型检查:可在编译阶段发现错误,避免了将错误带入到运行阶段,可提高程序正确性/健壮性,它能检测出如下错误:
(1). 语法错误:比如额外的标点符号或假词。即使是像Python这样的动态类型语言,也会进行这种静态检查。
(2).类名/函数名错误:like Math.sine(2) . (The right name is sin)
(3).参数数目错误, like Math.sin(30,20)
(4).参数类型错误, like Math.sin("30") ,(“30”是一个字符串)。
(5).返回值类型错误, like return "30"; from afunction that’s declared to return an int .

2.2Dynamic checking

动态类型检查:在执行代码时会自动发现错误。一般情况下,它能检测出:
(1).非法的参数值
. For example, the integer expression x/y is only erroneous when y is actually zero; otherwise it works. So in this expression, divide-by-zero is not a static error, but a dynamic error.
(2).非法的返回值, i.e. when the specific return value can’t be represented in the type.
(3).越界, e.g. using a negative or too-large index on a string.
(4).空指针,在空对象引用上面调用方法

2.3Static vs. Dynamic Checking

静态检查:关于“类型”的检查,不考虑值;它保证了一个变量将具有该某一集合中的一些值,但是直到运行时我们才知道它具体是哪个值。因此,如果错误只由某些值引起,比如除零或索引超出范围,那么编译器就不会对它产生静态错误。
动态检查:关于“值”的检查;相比之下,动态检查往往是关于由特定值引起的错误。

3.Mutability and Immutability

3.1Immutability 不变性

改变一个变量:将该变量指向另一个值的存储空间。
改变一个变量的值:将该变量当前指向的值的存储空间中写入一个新的值。
在编程时,应该尽可能避免变化,以避免副作用。
不变数据类型:一旦被创建,其值不能改变。
如果是引用类型,也可以是不变的:一旦确定其指向的对象,不能再被改变。例如:要使引用不可变,使用关键字final声明它:
如果编译器无法确定final变量不会改变,就提示错误,这也是静态类型检查的一部分。
注意:尽量使用 final变量作为方法的输入参数、作为局部变量,这是程序员的一种“设计决策”。
但是final类无法派生子类;final变量无法改变值/引用;final方法无法被子类重写。
不变对象:一旦被创建,始终指向同一个值/引用。
可变对象:拥有方法可以修改自己的值/引用。
例如:String as an immutable type
要在字符串 String 的末尾添加一些内容,必须创建一个新的字符串对象:

例如:StringBuilder as a mutable type
这个类有更改对象的值的方法,而不仅仅是返回新的值:

3.2Mutability and Immutability

当只有一个引用时,Mutability and Immutability之间的区别并不重要。但是,当对对象有其他引用时,它们的行为方式有很大的差异

3.3Advantage and Disadvantage of mutable types

Advantage
(1).使用不可变类型,对其频繁修改会产生大量的临时拷贝(需要垃圾回收),可变类型可以最小化拷贝以提高效率,获得更好的性能。例如如下代码

对于String,第一个数字(“0”)在构建最后一个字符串的过程中实际上被复制了n次,第二个数字被复制了n-1次,以此类推。 它实际上花费O(n²)时间来完成所有的复制,即使我们只连接了n个元素。
对于StringBuilder,它使用一个简单但聪明的内部数据结构,以避免做任何复制,直到最后,当要求与toString()调用的最终字符串。

(2).适合于在多个模块之间共享数据

Disadvantage:
可变性使您更难理解您的程序在做什么,也更难强制执行合同;不可变类型更容易避免bug,更容易理解,也更容易进行更改。例如:

该sumAbsolute()函数超出了spec范畴,因为它改变了输入参数的值!实际上,传递可变对象是一个潜在的错误。它只是在等待一些程序员无意中修改这个列表,通常是出于非常好的意图,比如重用或性能,但却会导致一个可能很难跟踪的(在该例中并不容易察觉到传递的列表已经被修改)bug.
因此对于 mutable types, 只有一个引用是安全的例如使用局部变量,因为它不会涉及共享;如果有多个引用(别名),使用可变类型就非常不安全。

3.4如何修改代码

(1).通过防御式拷贝,给客户端返回一个全新的 mutable types 对象,例如:
 
虽然大部分时候该拷贝不会被客户端修改,可能造成大量的内存浪费。
(2).因此,如果使用不可变类型,则节省了频繁复制的代价

4.Snapshot diagramas a code-level, run-time, and moment view

Snapshot diagrams用于描述程序运行时的内部状态,便于程序员之间的交流,便于刻画各类变量随时间变化,同时也便于解释设计思路 。

4.1Primitive and Object values in Snapshot Diagram

对于基本类型的值,原始值用裸常数表示。传入的箭头是对变量或对象字段中的值的引用。

 对于对象类型的值,对象值是用其类型标记的圆,当我们想要显示更多细节时,我们在其中写字段名,箭头指向它们的值。对于更详细信息,字段可以包括它们声明的类型。

对于不可变对象(如:String),在快照图中用双边框表示,就像我们的图中的String字符串对象一样。

对于可变对象(如:StringBuilder):

4.2Unreassignable/Immutable references ( final )

snapshot diagram中,不可重新分配的引用(final)用双箭头表示。

虽然引用是不可变的,但引用指向的值却可以是可变的(如: final StringBuilder sb )。同样的,可变的引用也可以指向不可变的值(如: String s )。
例如:

5.Useful immutable types

基本类型及其封装对象类型都是不可变的
Java的集合类型的通常实现——List, Set,Map——都是可变的:ArrayList, HashMap , etc. 集合实用程序类有一些方法来获取这些可变集合的不可修改的视图:
这种包装器得到的结果是不可变的:只能看;但是这种“不可变”是在运行阶段获得的,编译阶段无法据此进行静态检查

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值