HIT软件构造 复习笔记-2(4讲)
作者:互联网
一、Java中的数据类型
Java中主要有两种数据类型,基本数据类型和对象数据类型。下表列出了两种数据类型的对比:
ID和值:这里的ID是指在堆中的位置,对于对象数据类型,“==”比较的就是两个对象的ID是否相同。一般来说,比较对象数据类型的值用重写equals方法实现。而对于基本数据类型,由于没有ID,直接用“==”比较的就是他们值的大小。
可变和不可变:指源数据是否可以改变。不可变数据类型,如果想通过运算或者方法等改变它的值,就需要开辟新的存储空间,而源数据不受影响。如果是引用类型,则指向的对象不能改变(注意不是对象的值不可变,是只能指向这个对象)。可变数据类型会直接操作源数据,不会开辟新的存储空间。
immutable变量的实现方法:关键字final。尤其注意这里是变量不可变的实现方法,与数据类型是否可变区分开。
从上表可以发现,对象数据类型可以是可变或不可变的。String类对象就是一个不可变类型。
1 String s = "a"; 2 s = s.concat("b");
StringBuilder是可变数据类型。
1 StringBuilder sb = new StringBuilder("a"); 2 sb.append("b");
下面一个练习帮助更好的理解:第三行返回了一个String类对象,但并没有将s指向他。
1 String s = " Hello "; 2 s += " World "; 3 s.trim(); 4 System.out.println(s);
可变数据类型有一定的风险,他可能造成数据的破环,例如:
1 public static int sumAbsolute(List<Integer> list) { 2 int sum=0; 3 for(int i = 0; i < list.size(); i++) 4 list.set(i,Math.abs(list.get(i))); 5 for(Integer k:list) { 6 sum=sum+k; 7 } 8 return sum; 9 }
上面的代码将传入的list列表的内容破坏。
解决方式:防御式编程,即复制一份,在备份上操作。
1 public static int sumAbsolute(List<Integer> list) { 2 int sum=0; 3 List<Integer> list1=new ArrayList<>(list);//防御式编程 4 for(int i = 0; i < list.size(); i++) 5 list1.set(i,Math.abs(list.get(i))); 6 for(Integer k:list1) { 7 sum=sum+k; 8 } 9 return sum; 10 }
另外需要说明的是,Java中规定基本数据类型以小写字母开头,对象数据类型以大写字母开头。
- 对于基本数据类型,Java提供相应的对象类型。例如,Boolean和boolean,Integer和int。在实际应用中,很可能会用基本数据类型和对应的对象数据类型比较,这涉及到装箱与拆箱。JDK1.5以后,实现了自动拆装箱。
1 // 装箱操作 int -> Integer 2 int i = 5; 3 Integer integer = new Integer(i); 4 5 // 拆箱操作:Integer -> int 6 int num = integer.intValue();
二、检查
在介绍检查前,我们先明确一个概念。Java是静态类型语言,意味着在编辑阶段,编译器可以推断所有表达式的类型,在编译阶段完成类型检查。与之相对的是动态类型语言,例如python,它在运行阶段进行类型检查。
编程语言通常提供三种自动检查的方法:静态检查、动态检查、无检查。
静态检查:静态检查倾向于检查类型错误,与特定的值无关。
- 语法错误,如缺少分号
- 类名函数名错误
- 参数数目错误
- 参数类型错误
- 返回值类型错误
动态检查:检查那些由某些值引起的错误。
- 非法的变量值。如除零错误。
- 无法表示的返回值。如最后得到的返回值无法用声明的类型表示。
- 越界访问。如使用负数索引访问字符串。
- 空指针错误。如空指针对象调用方法。
区分动态检查和静态检查的关键点在于看错误是否由值来触发。
1 int n = 5; 2 if (n){ 3 n = n + 2; 4 } 5 //静态错误 6 7 int big = 2000000; 8 big = big * big; 9 //无错误,但结果不正确(溢出) 10 11 double probability = 1/5; 12 //无错误,但结果不正确(隐式类型转换) 13 14 int sum = 0; 15 int n = 0; 16 int average = sum/n; 17 //动态错误 18 19 double sum = 7; 20 double n = 0; 21 double average = sum/n; 22 //无错误,但结果不正确(Infinite)
三、快照图
基本数据类型无圈,对象数据类型有圈;
不可变类型双线,可变数据类型单线。(是否被final修饰)
四、Array和Collection
- 两者最大的区别就是Array规定容量,Collection不限制容量。
- 求长度方法:数组名.length | 集合名.size
- 集合只接受对象数据类型
五、用迭代器遍历不能使用remove方法
因为迭代器迭代逻辑为:判断存在迭代对象,返回迭代对象,索引+1,而remove方法调用完毕会更新容器的索引,造成无法全部遍历,引发异常。
六、一些细节
基本数据类型及其封装类对象都是不可变的。
List实现类的add方法是把引用添加进来。
标签:HIT,复习,检查,int,list,sum,数据类型,笔记,对象 来源: https://www.cnblogs.com/hit-0217/p/16343192.html