关于final修饰符的一点思考

背景

在看HashMap的源代码的时候,发现其中的每个键值对的类型为一个Node<K, V>,其中包含了一个成员变量hash,被final修饰符修饰,但是并没有被初始化。这就有点奇怪了。

为什么可以在声明时不直接赋值?

是因为不是所有的被final修饰的值都要在声明时马上赋值吗?之前看到的关于final修饰变量时基本上时这么说的呀。写了一个测试类,如下

1
2
3
4
5
6
class Demo1{
final int hi;
public Demo1(int hi){
this.hi = hi;
}
}

当注释掉构造器中的赋值语句之后,编译器报错。这或许是可以被理解的。当构造器执行完了之后,一个对象才会被创建完成,其中的成员变量才有可能被访问到,所以它在被访问到之前,还是完成了初始化,得到了值。

那它还是final变量吗?

当然是的。在this.hi = hi;后面,再添加一条语句如下,

1
2
3
4
5
6
7
class Demo1{
final int hi;
public Demo1(int hi){
this.hi = hi;
this.hi = 666;
}
}

此时编译器是报错的,因为final变量的值不能被改变。

那对于对象呢?

测试的结果与基本数据类型相同。

1
2
3
4
5
6
7
8
9
10
11
class Demo1{
final int hi;
final Demo2 demo2;
public Demo1(int hi){
this.hi = hi;
//this.hi = 666;
this.demo2 = new Demo2();
}
}

class Demo2{}

依旧无编译错误。

关于final修饰符的一点思考

https://eucham.me/2017/12/20/62df0eb93752.html

作者

遇寻

发布于

2017-12-20

更新于

2022-04-21

许可协议

评论