原文: https://beginnersbook.com/2014/07/final-keyword-java-final-variable-method-class/
在本教程中,我们将学习final关键字的用法。final关键字可以与变量,方法和类一起使用。我们将详细介绍以下主题。
1)final变量
2)final方法
3)final类
1)final变量
final变量只不过是常数。初始化后,我们无法更改final变量的值。让我们看看下面的代码:
class Demo{final int MAX_VALUE=99;void myMethod(){MAX_VALUE=101;}public static void main(String args[]){Demo obj=new Demo();obj.myMethod();}}
输出:
Exception in thread "main" java.lang.Error: Unresolved compilation problem:The final field Demo.MAX_VALUE cannot be assignedat beginnersbook.com.Demo.myMethod(Details.java:6)at beginnersbook.com.Demo.main(Details.java:10)
我们在上面的程序中遇到了编译错误,因为我们试图更改final变量MAX_VALUE的值。
注意:在大写(CAPS)中使用常量名称被认为是一种好习惯。
空白的final变量
在声明时未初始化的final变量称为空白final变量。我们必须在类的构造函数中初始化空白的final变量,否则会抛出编译错误(错误:变量MAX_VALUE可能尚未初始化)。
这是在类中使用空白final变量的方式:
class Demo{//Blank final variablefinal int MAX_VALUE;Demo(){//It must be initialized in constructorMAX_VALUE=100;}void myMethod(){System.out.println(MAX_VALUE);}public static void main(String args[]){Demo obj=new Demo();obj.myMethod();}}
输出:
100
什么是空白的final变量?
假设我们有一个Student类,其中有一个名为Roll No的字段。由于Roll No不应该在学生注册后更改,我们可以将其声明为类中的final变量但我们无法提前为所有学生初始化Roll No(否则所有学生都会有相同的Roll No)。在这种情况下,我们可以声明Roll No变量为空白的final,我们在对象创建期间初始化此值,如下所示:
class StudentData{//Blank final variablefinal int ROLL_NO;StudentData(int rnum){//It must be initialized in constructorROLL_NO=rnum;}void myMethod(){System.out.println("Roll no is:"+ROLL_NO);}public static void main(String args[]){StudentData obj=new StudentData(1234);obj.myMethod();}}
输出:
Roll no is:1234
更多关于 StackOverflow 和 Wiki 的空白final变量。
未初始化的静态final变量
声明期间未初始化的静态final变量只能在静态块中初始化。例:
class Example{//static blank final variablestatic final int ROLL_NO;static{ROLL_NO=1230;}public static void main(String args[]){System.out.println(Example.ROLL_NO);}}
输出:
1230
2)final方法
final方法无法覆盖。这意味着即使子类可以调用父类的final方法而没有任何问题,但它不能覆盖它。
例:
class XYZ{final void demo(){System.out.println("XYZ Class Method");}}class ABC extends XYZ{void demo(){System.out.println("ABC Class Method");}public static void main(String args[]){ABC obj= new ABC();obj.demo();}}
上面的程序会抛出一个编译错误,但是我们可以在子类中使用父类final方法而不会出现任何问题。让我们来看看这段代码:这个程序运行正常,因为我们没有覆盖final方法。这表明final方法可以继承,但它们不符合覆盖的条件。
class XYZ{final void demo(){System.out.println("XYZ Class Method");}}class ABC extends XYZ{public static void main(String args[]){ABC obj= new ABC();obj.demo();}}
输出:
XYZ Class Method
3)final类
我们不能扩展final类。考虑以下示例:
final class XYZ{}class ABC extends XYZ{void demo(){System.out.println("My Method");}public static void main(String args[]){ABC obj= new ABC();obj.demo();}}
输出:
The type ABC cannot subclass the final class XYZ
要记住的要点:
1)构造函数不能被声明为 final。
2)本地final变量必须在声明期间初始化。
3)接口中声明的所有变量默认为 final。
4)我们无法改变final变量的值。
5)final方法不能被覆盖。
6)final类不被继承。
7)如果方法参数被声明为final,则不能更改这些参数的值。
8)以所有大写字母命名final变量是一个好习惯。
9)final,finally和finalize确定了三个不同的术语。finally用于异常处理,finalize是在垃圾收集期间由 JVM 调用的方法。
