文章目录
- 静态/动态类型检查
- 可变/不变的数据类型
- 可变数据类型的危险性
- 不变数据类型的优越性
- 用Snapshot图理解数据类型
- 用集合类表达复杂数据类型
- 理解空指针的危害并避免它
数据类型
- 基本数据类型:小写字母,只有值,没有ID(与其他值无法区分),不可变,在栈中分配内存,代价低;
- 对象数据类型:Classes,interfaces ,arrays,enums,annotations.既有ID也有值,一些可变,一些不可变;在堆中分配内存,代价昂贵;
对于对象数据类型都有root,是Object。对象类型形成层次结构;
基本数据类型可封装形成对象类型(不可变的):Boolean,Integer,Short,Long,Character,Float,Double;通常是在定义集合类型的时候使用他们,一般情况下,尽量避免使用,一般可以互相自动转换;
重载:同样的操作名可用于不同的数据类型;
静态 vs. 动态数据类型检查
java作为一种静态类型语言,在编译阶段进行类型检查;
python作为一种动态类型语言,在运行阶段进行类型检查;
静态类型检查>>动态>>无检查
静态类型检查:可在编译阶段发现错误,避免将错误代入到运行阶段,可提高程序正确性/健壮性;
静态检查的内容:语法错误;类名/函数名错误;参数数目错误;参数类型错误;返回值类型错误;
动态检查:
- 非法的参数值;
- 非法的返回值;
- 越界;(例如:一个字符串中负数或太大的索引)
- 空指针;
趋向于对由于具体“值”引起的错误的检查;(例如:除0错误)
在例如Java的编程语言中,基本数据类型在某些情况不会表现的像真实的数字;结果使得有些错误静态/动态检查都无法检查到:
- 整数除法:5/2不会返回一个分数,而是会返回一个整数;
- 整数越界:例如int big = 200000*200000,会溢出返回一个错误的值;
- 浮点数中的特殊的值:POSITIVE_INFINITY,NEGATIVE_INFINITY,例如:double a = 7/0;
可变量和不可变量
改变一个变量:将该变量指向另一个值的存储空间;
改变一个变量的值:将该变量当前指向的值的存储空间中写入一个新的值;
不变性:重要设计原则;
不变数据类型:一旦被创建,其值不能改变;
如果引用类型,也可以是不变的:一旦确定其指向的对象,不能被改变;
如果编译器无法确定final变量不会改变,就提示错误;
final类无法派生子类;
final变量无法改变值/引用;
final方法无法被子类重写;
不变对象:一旦被创建,始终指向同一个值/引用;
可变对象:拥有方法可以修改自己的值/引用;
String是不可变类型;
StringBuilder是可变类型;
使用不可变类型,对其频繁修改会产生大量的临时拷贝(需要垃圾回收);
可变类型最小化拷贝以提高效率;
使用可变数据类型,可获得更好的性能;
也适合在多个模块之间共享数据;
不可变类型更“安全”,在其他质量指标上表现更好;
如何修改代码:
- 通过防御式拷贝,给客户端返回一个全新的Date对象;例如
return new Date (groundhogAnswer.getTime())
,然而大部分时候该拷贝不会被客户端修改,可能造成大量的内存浪费; - 如果使用不可变类型,则节省频繁复制的代价;
- 安全地使用可变类型:局部变量,不会涉及共享,只有一个引用;
- 如果有多个引用(别名),使用可变类型就非常不安全;
Snapshot diagram作为一个code-level,run-time,moment view
用于描述程序运行时的内部状态;
我们也可将一个可变的指针指向一个不可变的变量;
复杂数据类型:Arrays and Collections
从Array到Arrays.asList(new String[] {"a","b","c"})
我们不能建立一个基本数据类型的集合;
List ,Set,Map都是接口;
List:ArrayList 和LinkedList;
Set: HashSet;
Map: HashMap;
Iterator 迭代器是可变类型;
有用的不可变类型
基本数据类型及其封装对象类型都是不可变的;
Date是可变的;
可以对可变数据类型使用不可变的包装器,这种包装器得到的结果是不可变的:只能看;
- 例如:
Collections.unmodifiableList()
,这样包装一个List,使得它的set(),add(),remove()
等可变方法失效;
但是,这种“不可变”是在运行阶段获得的,编译阶段无法据此进行静态检查;
- 浅拷贝:对于基本数据类型来说,拷贝一份互不影响;而对于数组和对象来说,只会拷贝数组或者对象的引用,对新旧数组进行修改,两个数组都会发生变化。
- 深拷贝:指完全的拷贝一个对象,即使嵌套了对象,两者也相互分离,修改一个对象的属性,也不会影响另一个。
空指针
空指针可能会造成危害