原文链接https://www.cnblogs.com/dolphin0520/p/10651845.html
作者Matrix海 子
本文为笔记
0. 概述
final和static一样都是修饰词,final用来修饰类、方法、变量(包括局部变量和成员变量)。
1. final修饰类
被final修饰的类表示不可被继承,并且此时该类中的所有成员方法都会被隐式地修饰为final。
一般不把类定义为final类。
2. final修饰方法
说明这种方法提供的功能已经满足当前要求,不需要进行扩展,并且也不允许任何从此类继承的类来重写这种方法。
但是继承仍然可以继承这个方法,也就是说可以直接使用被final修饰的方法。在声明类中,一个 final 方法只被实现一次。
也就是只有明确不想被覆盖的方法会被修饰为final。
类的private方法会隐式地被指定为final方法。
3. final修饰变量
- 如果被修饰的变量是基本数据类型,则这个变量的值不会被改变。
- 如果被修饰的变量是引用类型,则这个变量初始化后无法指向其他对象,但是指向的对象的值可以发生改变。
3.1 final修饰成员变量
final修饰成员变量时,必须要保证该成员变量在被声明时或者构造器中就被赋值了,且一旦初始化完成,值就不能被改变了。
有如下代码
public class Test {
public static void main(String[] args) {
String a = \"hello2\";
final String b = \"hello\";
String d = \"hello\";
String c = b + 2;
String e = d + 2;
System.out.println((a == c));
System.out.println((a == e));
}
}
/*
true
false
*/
此处的结果蕴含着final的特点:当final修饰基本数据类型和String时,如果在编译器就能知道这个变量的值,则编译器会把它当做编译期常量使用,类似C中的宏。于是此时的a和c实际指向了同一个引用,而e指向的是一块新的引用。
但是这个特性实现的前提是在编译期间就能知道具体的值,而如下所示
public class Test {
public static void main(String[] args) {
String a = \"hello2\";
final String b = getHello();
String c = b + 2;
System.out.println((a == c));
}
public static String getHello() {
return \"hello\";
}
}
// false
上述代码在程序实际运行时,b才能通过调用getHello函数从而被初始化,所以无法在编译期间就获取到值,因此结果为false。
3.2 final修饰局部变量
注意Java中采用的是值传递,所以在调用时要注意。例如
public class Test {
public static void main(String[] args) {
MyClass myClass = new MyClass();
int i = 0;
myClass.changeValue(i);
}
}
class MyClass {
void changeValue(int i) {
i++;
}
}
//Error
上述代码会报错,因为在changeValue函数体中,i被识别为局部变量。而该变量为final,无法改变i的值。
4. final和static
修饰成员变量时,final保证不可变,static表示每个对象都有一份副本。
public class Test {
public static void main(String[] args) {
MyClass myClass1 = new MyClass();
MyClass myClass2 = new MyClass();
System.out.println(myClass1.i);
System.out.println(myClass1.j);
System.out.println(myClass2.i);
System.out.println(myClass2.j);
}
}
class MyClass {
public final double i = Math.random();
public static double j = Math.random();
}
// myClass1.i != myClass2.i
// myClass1.j == myClass2.j
i被修饰为final,表示不可变,而j表示所有对象共享同一个j,所以i不同,j相同。
来源:https://www.cnblogs.com/cayman98/p/15987807.html
本站部分图文来源于网络,如有侵权请联系删除。