原文: https://beginnersbook.com/2014/07/final-keyword-java-final-variable-method-class/

在本教程中,我们将学习final关键字的用法。final关键字可以与变量,方法和类一起使用。我们将详细介绍以下主题。

1)final变量

2)final方法

3)final

1)final变量

final变量只不过是常数。初始化后,我们无法更改final变量的值。让我们看看下面的代码:

  1. class Demo{
  2. final int MAX_VALUE=99;
  3. void myMethod(){
  4. MAX_VALUE=101;
  5. }
  6. public static void main(String args[]){
  7. Demo obj=new Demo();
  8. obj.myMethod();
  9. }
  10. }

输出:

  1. Exception in thread "main" java.lang.Error: Unresolved compilation problem:
  2. The final field Demo.MAX_VALUE cannot be assigned
  3. at beginnersbook.com.Demo.myMethod(Details.java:6)
  4. at beginnersbook.com.Demo.main(Details.java:10)

我们在上面的程序中遇到了编译错误,因为我们试图更改final变量MAX_VALUE的值。

注意:在大写(CAPS)中使用常量名称被认为是一种好习惯。

空白的final变量

在声明时未初始化的final变量称为空白final变量。我们必须在类的构造函数中初始化空白的final变量,否则会抛出编译错误(错误:变量MAX_VALUE可能尚未初始化)。

这是在类中使用空白final变量的方式:

  1. class Demo{
  2. //Blank final variable
  3. final int MAX_VALUE;
  4. Demo(){
  5. //It must be initialized in constructor
  6. MAX_VALUE=100;
  7. }
  8. void myMethod(){
  9. System.out.println(MAX_VALUE);
  10. }
  11. public static void main(String args[]){
  12. Demo obj=new Demo();
  13. obj.myMethod();
  14. }
  15. }

输出:

  1. 100

什么是空白的final变量?

假设我们有一个Student类,其中有一个名为Roll No的字段。由于Roll No不应该在学生注册后更改,我们可以将其声明为类中的final变量但我们无法提前为所有学生初始化Roll No(否则所有学生都会有相同的Roll No)。在这种情况下,我们可以声明Roll No变量为空白的final,我们在对象创建期间初始化此值,如下所示:

  1. class StudentData{
  2. //Blank final variable
  3. final int ROLL_NO;
  4. StudentData(int rnum){
  5. //It must be initialized in constructor
  6. ROLL_NO=rnum;
  7. }
  8. void myMethod(){
  9. System.out.println("Roll no is:"+ROLL_NO);
  10. }
  11. public static void main(String args[]){
  12. StudentData obj=new StudentData(1234);
  13. obj.myMethod();
  14. }
  15. }

输出:

  1. Roll no is:1234

更多关于 StackOverflowWiki 的空白final变量。

未初始化的静态final变量

声明期间未初始化的静态final变量只能在静态块中初始化。例:

  1. class Example{
  2. //static blank final variable
  3. static final int ROLL_NO;
  4. static{
  5. ROLL_NO=1230;
  6. }
  7. public static void main(String args[]){
  8. System.out.println(Example.ROLL_NO);
  9. }
  10. }

输出:

  1. 1230

2)final方法

final方法无法覆盖。这意味着即使子类可以调用父类的final方法而没有任何问题,但它不能覆盖它。

例:

  1. class XYZ{
  2. final void demo(){
  3. System.out.println("XYZ Class Method");
  4. }
  5. }
  6. class ABC extends XYZ{
  7. void demo(){
  8. System.out.println("ABC Class Method");
  9. }
  10. public static void main(String args[]){
  11. ABC obj= new ABC();
  12. obj.demo();
  13. }
  14. }

上面的程序会抛出一个编译错误,但是我们可以在子类中使用父类final方法而不会出现任何问题。让我们来看看这段代码:这个程序运行正常,因为我们没有覆盖final方法。这表明final方法可以继承,但它们不符合覆盖的条件。

  1. class XYZ{
  2. final void demo(){
  3. System.out.println("XYZ Class Method");
  4. }
  5. }
  6. class ABC extends XYZ{
  7. public static void main(String args[]){
  8. ABC obj= new ABC();
  9. obj.demo();
  10. }
  11. }

输出:

  1. XYZ Class Method

3)final

我们不能扩展final类。考虑以下示例:

  1. final class XYZ{
  2. }
  3. class ABC extends XYZ{
  4. void demo(){
  5. System.out.println("My Method");
  6. }
  7. public static void main(String args[]){
  8. ABC obj= new ABC();
  9. obj.demo();
  10. }
  11. }

输出:

  1. 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)finalfinallyfinalize确定了三个不同的术语。finally用于异常处理,finalize是在垃圾收集期间由 JVM 调用的方法。