您的位置:首页 > 编程语言 > Java开发

java基础:关于final关键字

2017-06-01 15:35 225 查看

final 关键字

首先,我们先来区分一下,final finally关键字与finalize()方法之间的区别。他们三者唯一的相同点就是都是final这几个字母打头,其他就没有什么相同点了。

finally关键字是异常处理时用到的,语义是用finally修饰的代码块一定会被执行,不管是否产生异常。所以一般关于各种流、数据库连接的关闭还有lock的unlock操作都写在该代码块中。

finalize()方法是在java.lang.Object里定义的。垃圾回收器准备释放内存的时候,会先调用finalize()方法。GC收集器会自动解决大部分垃圾的回收,除非有必要,应当避免使用该方法。

final关键字的含义是“终态”的意思,可以修饰类,变量和方法,表示这是无法改变的。从继承的角度上讲,它的语义是和abstract正好相反,所以它不能修饰抽象的类与方法。被final修饰的方法与类是不能被重写与继承的,而被它修饰的变量是不能被改变的,且该变量必须被初始化(直接在声明变量的时候或者在构造方法中赋值),否则编译报错。

“这是不能被改变的”

* Created by fei on 2017/6/1.
*/
public class TestFinal {
private final String finalVar = "abc";
public TestFinal(){
// finalVar = "abc";
}

public static void main(String[] args) {
final String str = new String("abc");
System.out.println("改变之前的值:"+str+",哈希值"+str.hashCode());
str = "def"; //编译报错,在idea里显示的错误信息是:无法为最终变量str分配值
System.out.println("改变之后的值:"+str+",哈希值"+str.hashCode());
}
}


这个很好理解,因为不是说了嘛,用final修饰的变量初始化之后是不能改变的,即使初始化为null,之后也不能被改变。但我们来看下一个例子:

* Created by fei on 2017/6/1.
*/
public class TestFinal {
private final String finalVar = "abc";
public TestFinal(){
// finalVar = "abc";
}

public static void main(String[] args) {
//这里改成了 StringBuffer
final StringBuffer str = new StringBuffer("abc");
System.out.println("改变之前的值:"+str+",哈希值"+str.hashCode());
str.append("def"); //没有报错
System.out.println("改变之后的值:"+str+",哈希值"+str.hashCode());
}
}


很简单,就是将String类变成了StringBuffer类,再运行一下:

改变之前的值:abc,哈希值1735600054
改变之后的值:abcdef,哈希值1735600054


没有报错?不是说不能改变吗?其实看到打印的哈希值就应该理解final到底是怎么回事了,并不是变量的值不能改变,而是变量的引用不能改变。为了验证一下,我将 str.append(“def”) 这条语句变为这样:str = new StringBuffer(“abc”) 注意,这里连赋的值都是一样的‘abc’,但是确实像我们想象的那样,编译报错,因为引用改变了。这个还可以利用容器类进行测试,比如list map等等,这里就不再进行演示了,只要不改变容器类的引用,是可以对容器中的元素进行增删改操作的。

为什么说 final 与 abstract 是语义相反的

abstract 是告诉程序员:我可以被继承哦,你可以重写实现自己的方法哦,快来吧,我给你无限的发挥空间。而final说的是:对不起,我已经是你想要的最好的了,你可以继承我修饰的方法,但我已经实现了你想要的东西,我不需要扩展,也不需要你来重写我。

针对final ,我们具体的看一下用它修饰的类、方法都是一些什么含义(变量就不再继续详述了)

被final修饰的类是不能被继承的,当然,这个类的方法也就没有被子类重写的机会。

被final修饰的方法不能被子类的方法覆盖,但可以被继承。当然这里说的类是不被final修饰的类。

final不能修饰构造方法。而且值得注意的是因为父类用private修饰的方法也是不能被子类覆盖的,所以private类型的方法默认也是final的。

还有一点就是final还可以修饰参数,它的语义很修饰变量是一样的,都是不能改变。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java final 关键字 哈希