final关键字介绍
final
是Java语言中的一个关键字,主要用于修饰不变的东西,告诉编译器这个对象(变量,方法,对象)是不可变的,在Scala中的val
通过编译为Java字节码后,其实现方式就是final
。
final的用法
一提起final修饰引用的问题,我就想起了C++中的const
,const
可以修饰指针,但可以写成
const int *pointer
int* const pointer
一个是确保指针指向的对象不可变,另一个是只身的引用不可变,类似的Java中的final
也有类似的用法。
final修饰变量
final
如果用于修饰基本变量,比如int
,double
等类型时,该值就是不可变的。
final int a = 1;
final double b = 0.60;
如果用于修饰非基本类型,比如List
,Map
,CustomObject
,引用不可变,但所引用的内容是可以变的。
final List<String> list = Arrays.asList("abc", "xyz");
list.add("ccc");
final
修饰变量有三种初始化方式:
- 定义时初始化
- 构造器中初始化
- 非静态块中为
final
实例变量设置值 -
static
的final
需在static
中被初始化
final修饰方法
以下这个方法treeifyBin
就是HashMap中在1.8中引入的变化,再同一个桶中如果冲突的元素过多,则把链表转换为红黑树。
final void treeifyBin(Node<K,V>[] tab, int hash) {
int n, index; Node<K,V> e;
if (tab == null || (n = tab.length) < MIN_TREEIFY_CAPACITY)
resize();
else if ((e = tab[index = (n - 1) & hash]) != null) {
TreeNode<K,V> hd = null, tl = null;
do {
TreeNode<K,V> p = replacementTreeNode(e, null);
if (tl == null)
hd = p;
else {
p.prev = tl;
tl.next = p;
}
tl = p;
} while ((e = e.next) != null);
if ((tab[index] = hd) != null)
hd.treeify(tab);
}
}
这个方法就是被声明为final
的,final
的用意在于该方法不能重写,并且因为final
有一个隐喻就是在编译期被定义为常量的东西有可能被编译器优化,如果方法被定义为final,则会被编译器在做inline
操作。
final修饰对象
final
如果用于修饰对象的话,则该对象不可继承,用于定义一个不可变的class
。比如,大名鼎鼎的String
。
不可继承的类作用就是1.安全性 2. 性能。保证常量不被覆写,性能通过编译器得到优化。
引申问题
String
初始化的方式有哪些?new String("111")
和String str = "111"
的值引用一样吗?哪个在堆上,哪个在常量池上?
下篇文章介绍
网友评论