final关键字解析
final在Java中很常用,它为我们提供了诸如在C语言中定义常量的功能,不仅如此,final还可以让你控制你的成员、方法或者是一个类是 否可被覆写或继承等功能,这些特点使final在Java中拥有了一个不可或缺的地位,也是学习Java时必须要知道和掌握的关键字之一。
1.修饰基本类型时,那便是说其值不可变(永远不改变的的编译期常量)
编译期常量是指在编译器编译时就可以将该常量值带入如何可能用到它的计算式中。可以在编译时作出计算,减轻了运行时的负担,这类常量必须是基本数据类型,在定义时,必须对其赋值。
public class StringTest {
private final int i = 2;
public int upcase(String s){
//在编译期的时候就已经知道这个返回结果是5,不需要在运行的时候计算
return i+3;
}
}
2.修饰对象变量时,那便是说其引用不可再变。
一旦引用对象使用final定义,那么表示该引用恒定不变,一旦引用被初始化指向一个对象。就无法再把它改为指向另外一个对象,但是对象自身是可以修改的
对后面一句话“对象自身是可以修改”的,这个很容易理解,引用不变,其他则可变。如下代码
public void testStringBuffer(){
final StringBuffer sb = new StringBuffer("1");
sb.append("2");
sb.append("3");
//输出结果是123,表明验证了这句话,对象自身是可以变的
System.out.println(sb.toString());
}
一旦引用被初始化指向一个对象。就无法再把它改为指向另外一个对象”
public static void main(String[] args) {
//引用已经被固定了,只能指向how这个堆内存空间
final String s = "how";
//如果执向其他堆内存,则编译时会出错
//s = "old";
}
什么时候初始化final常量
final初始化常量有两种方式,
1.在声明的时候初始化其值
2.在构造方法中初始化其值
private final int i;
private final int k = 2;
public StringTest(){
i = 2;
}
那么这两种初始化的时机有什么区别呢?
在使用上没有什么区别,但是在构造方法中初始化却显的更灵活。如代码
package com.ur.test;
public class StringTest {
private final int i;
public StringTest(){
i = 1;
}
public StringTest(int p){
i = p;
}
public StringTest(int p, int c){
i = c;
}
public static void main(String[] args) {
//发现常量i却会根据对象不同构造而变化
new StringTest();//i为1
new StringTest(2);//i为2
new StringTest(2, 3);//i为3
}
}
final参数
你可以接受我,但是不能改变我!(final参数本质)
public void get(final Date time){
time = new Date();
//The final local variable time cannot be assigned.
//It must be blank and not using a compound assignment
}
可以看到在编译时就提示常量不能改变。
final参数这一特性鼠药会用在匿名函数中
final方法
我就是我,谁也别想改变!
使用final方法的原因有两个。
1.把方法锁定,防止任何继承类修改它的含义
2.出于效率的考虑(新版本中可以不用考虑)
注意:
在一个类中所有的private方法,都被隐式的被声明为final类,因为子类无法覆盖private方法。
final类
如果一个类修饰为final,那么它连子类都没有了。
出于这样设计的目的是
1.不希望有任何的类继承我。
注意:
在一个类中所有的方法,都被隐式的被声明为final方法