final关键字的作用
final关键字可以修饰类、属性和方法。
- final修饰一个类时,说明这个类不能不继承,基础类库String、System等是被final修饰的。
- final修饰属性时,代表这个变量是常量,能且只能被赋值一次。
- final关键字修饰的类成员变量,必须在定义的时候显式的赋初始值。
- final关键字修饰的对象成员变量,也必须显式的赋值,既可以在定义的时候赋初始值,也可以在所有的构造函数中,给其赋初始值。
- final修饰一个方法时,代表这个方法不能被重载(Override)。但是,如果这个方法同时被private关键字修饰,则是可以被“重写”的。这是因为按照private定义,子类无法知道父类定义的函数和属性,所以给“重写”加上了引号。
final常量和普通变量的差异
请看下面的一个代码片段。
按照正常的思路,第8行和第9行输出的结果是false。如果去运行这段代码,第8行输出的结果却是true。
这里面体现了final变量和普通变量的区别,当final变量是基本数据类型以及String类型时,如果在编译期间能知道它的确切值,则编译器会把它当做编译期常量使用。也就是说,在编译期间,编译器已经把计算后的结果,赋值给了变量。这种和C语言中的宏替换有点像。因此在上面的一段代码中,因为A是常量,编译器直接把计算后的结果,即“hello world”赋值给了c,相当于直接定义String c = "hello world"。不过要注意,只有在编译期间能确切知道计算后的结果时,编译器才会进行这样的优化。如果我们把上面的代码修改一下,就不起作用了。输出的结构都是false。
final & finalize & finally
这三个词,虽然长得很像,含义也相近,但是在java语言中,却是完全不同的概念,不要混淆了。
finalize(),是Object类的一个函数,类似于C++里的析构函数,在jvm垃圾回收的时候执行,由jvm调度。一般情况下,不需要程序员重载此函数。
finally关键字和try、catch关键字一起使用,在这个组合中,catch和finally是可选的。finally修饰的代码块,表示最后执行并且保证会被执行到的代码。下面的两个代码片段,比较有代表性。
- 第1个代码块,执行结果是1。说明finally代码块在return语句后执行,并且覆盖了return的返回值。
- 第2个代码块,执行结果也是1,并不会抛出异常。说明finally代码块在throw语句之后执行,并且覆盖了throw的异常。关于这点,java语言的设计只允许有一个返回值,void、异常算是一种特殊的返回值,finally执行的语句,会覆盖之前执行代码的返回值。
这是一个基础的问题,不要在小问题上翻船了。希望我的分享对各位有所帮助,欢迎关注我。正在持续更新《面试夺命三问》系列和《架构实战》系列。