Java final关键字

final可以用来修饰数据、方法和类。

一、 final数据

1. 用于基本类型

定义一个永不改变的编译时常量(编译时值已经确定);定义一个在运行时被初始化的值,一旦被初始化,就无法改变。

2. 用于对象引用

使引用恒定不变,即一旦引用被初始化指向某一对象,就无法再指向其他对象。但是被指向的对象本身是可以改变的。

import java.util.Random;

class Value{
	int i;
	public Value(int i) {this.i = i;}
}

public class TestFinal {

	private static Random rand = new Random(47);
	private final int valueOne = 9;
	private static final int VALUE_TWO = 99;
	public static final int VALUE_THREE = 999;
	
	private final int i4 = rand.nextInt(20);
	static final int INT_5 = rand.nextInt(20);
	
	private Value v1 = new Value(11);
	private final Value v2 = new Value(22);
	private static final Value VAL_3 = new Value(33);
	
	private String id;
	
	public TestFinal(String id) {
		this.id = id;
	}
	
	public String toString() {
		return id + ":" + "i4 = " + i4 + " INT_5 =" + INT_5;
	}

	public static void main(String[] args) {
		TestFinal tf1 = new TestFinal("tf1");
//		tf1.valueOne++;//The final field TestFinal.valueOne cannot be assigned
//		tf1.VALUE_TWO++;//The final field TestFinal.VALUE_TWO cannot be assigned
//		tf1.VALUE_THREE++;//The final field TestFinal.VALUE_THREE cannot be assigned
		
		tf1.v1 = new Value(9);		
//		tf1.v2 = new Value(9); //The final field TestFinal.v2 cannot be assigned
		tf1.v2.i++;		
//		tf1.VAL_3 = new Value(3);//The final field TestFinal.VAL_3 cannot be assigned
		
		System.out.println(tf1);
		TestFinal tf2 = new TestFinal("tf2");
		System.out.println(tf2);
	}

}

 

tf1:i4 = 15 INT_5 =18
tf2:i4 = 13 INT_5 =18

valueOne, VALUE_TWO,VALUE_THREE 都是final int,是编译期常量,不能被改变,static关键字只是强调只有一份,没有什么本质区别。VALUE_THREE是一种更加典型的常量定义方式,被定义为public,则可以被用于包之外,static表示只有一份,final表示其为常量。

i4,INT_5说明了final定义的数据也可以时运行时才确定其值。i4对于每个对象都是独特的,即每次创建一个新的对象,就会初始化产生一个i4。但是由于INT_5是static的,在类装载的时候被初始化,只有唯一的一份。所以对于tf1和tf2,i4的值是不同的,INT_5则相同。

对于对象引用,v2和VAL_3不能再指向其他对象,但是它们指向的对象的内容依然是可以改变的。

3.用于方法参数

在参数列表中被指定为final的参数,在在方法中无法被改变:

1.如果该参数是对象引用,则在方法中不能更改该参数引用所指向的对象;

2.如果是基本类型,数据的值不能被改变。

class Demo{

}	

void with(final Demo d) {
//		d = new Demo(); //The final local variable d cannot be assigned. It must be blank and not using a compound assignment
}
	
void f(final int i) {
//		i++;//The final local variable i cannot be assigned. It must be blank and not using a compound assignment
}

二、final方法

final方法无法被继承类修改它的含义,无法被覆盖。而private关键字定义的方法,无法被继承类访问,则已隐式地被指定为了final,所以private方法不需要再添加final修饰词。

三、final类

被定义为final的类不允许被继承,其所有方法都隐式被指定为final方法。

### final 关键字的使用 final 关键字可以修饰类、方法和变量。 - **修饰类**:表明该类是最终类,不能被继承。示例代码如下: ```java final class FinalClass { // 类的内容 } // 以下代码会报错,因为 FinalClass 不能被继承 // class SubClass extends FinalClass {} ``` - **修饰方法**:表明该方法是最终方法,不能被重写。不过,final 方法是可以被重载的。示例代码如下: ```java class ParentClass { final void finalMethod() { System.out.println("This is a final method."); } final void finalMethod(int num) { // 重载 final 方法 System.out.println("Overloaded final method with num: " + num); } } class ChildClass extends ParentClass { // 以下代码会报错,因为 final 方法不能被重写 // void finalMethod() { // System.out.println("Trying to override final method."); // } } ``` - **修饰变量**:表明该变量第一次赋值后,不能被再次赋值(有且仅能被赋值一次)。如果 final 修饰的变量是基本类型,那么变量存储的数据值不能变;如果是引用类型,那么变量存储的地址不能发生改变,但是地址指向的对象的内容是可以发生变化的。示例代码如下: ```java class FinalVariableExample { final int basicVar = 10; // basicVar = 20; // 会报错,因为 basicVar 不能再次赋值 final StringBuilder refVar = new StringBuilder("Initial"); refVar.append(" Value"); // 可以修改对象内容 // refVar = new StringBuilder("New"); // 会报错,因为 refVar 的地址不能改变 } ``` ### final 关键字的作用 - **修饰类**:防止类被继承,保证类的安全性和完整性,例如 Java 中的 `String` 类就是被 final 修饰的,避免其被恶意继承和修改 [^2]。 - **修饰方法**:防止方法被重写,确保方法的实现逻辑不被改变,提高代码的稳定性。 - **修饰变量**:保证变量的值或引用的稳定性,避免意外修改,提高代码的可读性和可维护性。常量是使用了 `public static final` 修饰的成员变量,可用于做系统的配置信息,方便程序维护,同时也能提高可读性 [^2]。 ### final 关键字的原理 - **常量的执行原理**:在编译阶段会进行“宏替换”,把使用常量的地方全部替换成真实的字面量。好处是让使用常量的程序执行性能与直接使用字面量是一样的 [^2]。 - **final 域重排序规则**: - **final 域为基本类型**:写 final 域重排序规则确保在构造函数内对 final 域的写入,与随后把这个被构造对象的引用赋值给一个引用变量,这两个操作之间不能重排序;读 final 域重排序规则确保初次读一个包含 final 域的对象的引用,与随后初次读这个 final 域,这两个操作之间不能重排序 [^1]。 - **final 域为引用类型**:对 final 修饰的对象的成员域写操作和读操作也有相应的重排序规则,保证 final 引用对象的成员域的可见性 [^1]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值