前言
最近在复习,感觉类型检查那部分细节比较多,final修饰符也会涉及到类型检查,所以就把这两个知识点综合起来总结一下。
一、类型检查
1.静态类型检查
Java是一种静态类型的语言。
----所有变量的类型在编译的时候就已经知道了,然后编译器也会导出所有表达式的类型。
----如果a和b为int类型,那么编译器会推断a+b也是int类型。
----eclipse环境会在你写代码的时候就做这些事情,所以你在写代码的时候就会发现eclipse可能报出一些错误。
----静态类型检查在编译阶段进行。
在编译阶段发现错误,避免了将错误带到运行阶段,可提高程序正确性。
一般是类型相关的错误。如语法错误,类名、函数名错误,参数数目、类型错误,返回值类型错误。
int n=1;
if (n) n++;
在eclipse中输入这段代码时,在第二个n处会有红色波浪线,因为和C不一样,Java的判断语句内必须的boolean类型的。所以编译器在编译阶段就会报错。
2.动态类型检查
在像python这样的动态类型语言中,这种检查推迟到运行时候。
----在运行阶段进行类型检查。
一般的错误有非法的参数值,非法的返回值,越界,空指针。
int a=1,b=0;
System.out.println(a/b);
在eclipse中输入这段代码,没有运行时,不会报错。但运行后会抛出异常:Exception in thread “main” java.lang.ArithmeticException: / by zero。这是在运行阶段进行检查的动态类型检查。
二、可变数据类型和不可变数据类型
1.可变数据类型
可变数据类型是当改变一个变量的值时,将该变量当前指向的值的存储空间中写入一个新的值。
比如StringBuilder是一种可变的数据类型。
StringBuilder sb=new StringBuilder("a");
sb.append("b");
其内部的过程可以由这个图来表示:
2.不可变数据类型
不可变数据类型是改变一个变量,将该变量指向令一个值的存储空间。
比如String是一种不可变的数据类型。
String s="a";
s=s.concat("b");
其内部的过程可以由这个图来表示:
final修饰符
用final修饰class可以阻止被继承;修饰method可以阻止被子类重写;修饰field可以阻止被重新赋值;修饰局部变量也可以阻止被重新赋值。
下面主要讨论final分别修饰可变和不可变数据类型与静态类型检查的情况。
修饰可变类型
以StringBuilder为例。
final StringBuilder sb=new StringBuilder("a");
sb.append("b");
这段代码没有任何问题,代码快照图和上文可变数据类型的图相同。依然是同一个空间,只是空间里的值不同了。
final StringBuilder sb=new StringBuilder("a");
sb=new StringBuilder("ab");
这段代码在第二个sb处就会有红色波浪线,因为有final修饰,无法改变变量指向的对象。对于可变数据类型,final使得变量无法改变其引用。
修饰不可变类型
以String为例。
final String s="a";
s=s.concat("b");
和上文的图相同,String是不可变的数据类型,无法修改值,只能重新创建一个空间。这段代码就想要重新创造一个空间,这个空间里面的内容是“ab”,然后让s指向这个空间。显然会报错,因为有final修饰,s无法改变其指向。所以说,对于不可变数据类型,一旦被创建,其值不能改变。