final关键字
- 作用:一般是指不可改变的的
- 应用场景:数据、方法、类
一 定义数据
- 在编译器期常数
- 将常数值封装,不会随不同对象的创建而不同
- 一般只适用于基本数据类型
- 可以节省运行时的开销,在编译的时候就执行了
- 在运行期初始化的值
- 修饰的是对象句柄,句柄为常量;可以是基本数据类型,也可以是类;但是必须在构造方法中对句柄进行初始化
- 对象本身不可以更改(该句柄不可以再指向其他对象,不可在对其new对象)
- 但是对象的内容可以修改(类似单例模式,自己的理解)
- 也适用于数组,数组也是特殊的对象
public class TestFinal {
int i1 = 1;
final int i2 = 2;
static final int i3 = 3;
//基本数据类型句柄
final int i4;
//类对象句柄
final A a1;
final int[] a;
public void show() {
System.out.println("i1:"+i1+"i2:"+i2+"i4:"+i4+"数组a:"+a[1]);
}
public TestFinal() {
i4 = (int) (Math.random()*20);
a1 = new A();
}
public static void main(String[] args) {
TestFinal aFinal = new TestFinal();
//可以对a1的内容进行修改
aFinal.a1.ashow(2);
aFinal.a1.ashow(4);
aFinal.show();
TestFinal bFinal = new TestFinal();
bFinal.show();
//不允许创建
aFinal.a1 = new A();
}
class A {
void ashow( int i) {
i++;
System.out.println("A类"+i);
}
}
}
3.空白final
- 定义:一种特殊的字段;被声明为final,但没有立即对他进行初始值;这只是将初始值的初始化推迟到执行时,通过传参,或构造器中初始化。
- 通过构造函数进行传参初始化,可以使创建的不同对象的final修饰的句柄值不一样,但是还依旧保持着“不变的特性”—创建后的对象,不可以对其更改了
- 也用到构造函数的重载
public class BlankFinal {
final int i1;//空白final
final Property p;//空白final
public BlankFinal() {
i1 = 1;
p = new Property();
}
public BlankFinal(int x) {
i1 = x;
p = new Property();
}
public static void main(String[] args) {
BlankFinal aBlankFinal = new BlankFinal(2);
System.out.println(aBlankFinal.i1);
}
class Property {
}
}
4. final自变量
- 定义:方法的自变量设计为final属性,则在这个方法的内部,不能改变自变量句柄指向的变量,只可以使用。
- 这个final属性可以是传一个null,不会报错,这与非final变量操作一样
- 基本数据类型的自变量为fianl时,只能读取,不可改变
“java的八个基本数据类型”:
- 字符型:char 16
- 布尔类型:boolean 只有true和false两种结果
- 数值型:byte 8、short 16、int 32、long 64、float 32、double 64
public void show(final int i3) {
int k = 0;
k = i3 + 2;
System.out.println(k);
//System.out.println(i3++);提示错误不允许修改final值
}
二 定义方法
- 适合场合:
- 方法的代码量非常少,想提高程序的执行效率
- 想给方法上锁,禁止该方法被重写和覆盖时,才考虑。
- 类内的private方法都自动成为final
三 定义类
- 将类定义为fianl,则会该类将禁止被继承
- 其内部的方法也会默认时final的
- 成员变量不会被默认为final