文章目录
数据类型与类型检验
1 基本数据类型、对象数据类型
-
比较
-
包装类Boxed primitives
- 将基本数据类型包装成对象数据类型,: Boolean, Integer, Short, Long, Character, Float, Double
- 通常是在定义容器类型的时候使用它们(容器类型操作的元素要求是对象类型,所以需要对基本数据类型进行包装,转换为对象类型)如List,Map,Set等
- 一般情况下可以和对应的基本数据类型自动转换,但会降低性能,尽量避免使用
2 静态/动态类型检查
-
静态/动态类型语言
- 静态类型语言:所有变量的类型在编译时已知,编译器可以推导表达式类型,可以在编译阶段进行类型检查
- 动态类型语言:变量类型在编译时未知或不需要知道,在运行阶段进行类型检查
-
一种语言可以提供3种检查:
-
静态检查:在编译之前进行检查,关于类型的检查
- 语法错误
- 类名/函数名错误
- 参数数目错误
- 参数类型错误
- 返回值类型错误等
-
动态检查:在运行过程中进行检查,关于值的检查
- 检查非法的参数值
- 非法的返回值
- 越界
- 空指针
-
无检查:不进行检查
-
静态检查>动态检查>无检查
-
No error, but wrong answer
-
有些问题静态检查和动态检查都无法检测出来,如整数除法(截断整数)、整数溢出、浮点数的特殊类型:NaN,POSITIVE_INFINITY,NEGATIVE_INFINITY
-
3 Mutable/Immutable
-
改变一个变量/改变一个变量的值
- 改变一个变量:将该变量指向另一个值的存储空间
- 改变一个变量的值:将该变量当前指向的值的存储空间中写入一个新的值
-
不变性和可变性(重要设计原则)
-
(
final
+不可变数据类型)- 变量在赋值之后,就不能再进行修改
- 如
final String
、final int
-
(不可变数据类型)
- 变量的指向可变,存储空间中的值不可变
- 一旦被创建,其指向的存储空间中的值不能改变
- 修改变量时,会创建一个新的存储空间放入修改值,变量再指向新的存储空间。新的存储空间中的值也不能改变
- 如
int
等所有基本数据类型、String
等一些对象数据类型
-
(
final
+可变数据类型)- 变量的指向不可变,存储空间中的值可变
- 修改变量时,修改存储空间中的值
- 不能再次使用
new
指向新的存储空间 - 如
final StringBuilder
-
(可变数据类型)
- 变量的指向可变,存储空间中的值可变
- 可以修改存储空间中的值
- 可以再次使用
new
指向新的存储空间 - 如
StringBuilder
-
4 值的改变、引用的改变、final
-
值的改变、引用的改变
当只有一个引用指向该对象时,二者没有区别;当有多个引用的时候,有差异
-
final
- final类无法派生自己的子类
- final变量无法改变值/引用(不能指向新的存储空间)
- final方法无法被子类重写
5 防御式拷贝
-
原理
- 构造方法中,将内部的表示与外部的变量建立关系,如果变量是可变的,则需要进行防御式拷贝
- 返回时,如果内部表示是可变的,如果直接返回回去,则使内部的表示和外部的变量建立了引用,因此也需要防御式拷贝
-
危险示例
- 将传入的可变类型参数修改了,再次使用时值已经发生变化
- 将传入的可变类型参数修改了,再次使用时值已经发生变化
-
实现
-
防御式拷贝的具体实现:创建副本进行传递或者强转为对应的不可变数据类型
-
6 Snapshot diagram
- 表示
-
基本数据类型的值
由裸常量表示,传入箭头是对变量或对象字段中的值的引用
-
对象数据类型的值
-
是按其类型标记的圆,在里面写下字段名,用箭头指向它们的值。
-
不可变对象(存储空间的中的值不可变):用双线椭圆表示
-
不可变引用(变量的指向不可变):用双线箭头表示
-
- 练习
-
final
+可变数据类型,不能再次使用new
指向新的存储空间
-
List
中[0]添加变量时,都是指向该变量指向的具体存储空间,变量指向变化时,List
中[0]指向不变
-
*7 复杂数据类型:数组和集合
-
Array:定长数组
- 定义:
int [] a = new int [3]; //长度为3的定长数
- 方法:
indexing: a[2] assignment: a[2]=0 length: a.length
- 定义:
-
List:变长数组
- 定义:
List<String> firstNames = new ArrayList<>(); List<String> lastNames = new LinkedList<>();
- 方法:
indexing: list.get(2) assignment: list.set(2, 0) length: list.size()
- 定义:
-
set:集合:无序、不可重复,与list有区别
- 定义:
Set<Integer> numbers = new HashSet<>();
- 方法:
s.contains(e); s.containsAll(s2); s.removeAll(s2)
- 定义:
-
Map:字典数据类型,将两组对象匹配(映射)
- 定义:
Map<String,Turtle> turtles = new HashMap<>();
- 方法:
map.put(key,a1);//建立映射key->a1 map.get(key);//得到key对应的值 map.containsKey(key)//判断是否含有key map.remove(key)//删除某个匹配
- 定义: