# Java 中的`final`关键字 - `final`变量，方法和类

> 原文： [https://beginnersbook.com/2014/07/final-keyword-java-final-variable-method-class/](https://beginnersbook.com/2014/07/final-keyword-java-final-variable-method-class/)

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

1）`final`变量

2）`final`方法

3）`final`类

## 1）`final`变量

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

```java
class Demo{  

   final int MAX_VALUE=99;
   void myMethod(){  
      MAX_VALUE=101;
   }  
   public static void main(String args[]){  
      Demo obj=new  Demo();  
      obj.myMethod();  
   }  
}
```

**输出：**

```java
Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
	The final field Demo.MAX_VALUE cannot be assigned

	at 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`变量的方式：

```java
class Demo{  
   //Blank final variable
   final int MAX_VALUE;

   Demo(){
      //It must be initialized in constructor
      MAX_VALUE=100;
   }
   void myMethod(){  
      System.out.println(MAX_VALUE);
   }  
   public static void main(String args[]){  
      Demo obj=new  Demo();  
      obj.myMethod();  
   }  
}
```

**输出：**

```java
100
```

**什么是空白的`final`变量？**

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

```java
class StudentData{  
   //Blank final variable
   final int ROLL_NO;

   StudentData(int rnum){
      //It must be initialized in constructor
      ROLL_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();  
   }  
}
```

**输出：**

```java
Roll no is:1234
```

更多关于 [StackOverflow](https://stackoverflow.com/questions/11345061/why-must-a-final-variable-be-initialized-before-constructor-completes) 和 [Wiki](https://en.wikipedia.org/wiki/Final_%28Java%29#Blank_final) 的空白`final`变量。

### 未初始化的静态`final`变量

声明期间未初始化的静态`final`变量只能在[静态块](https://beginnersbook.com/2013/04/java-static-class-block-methods-variables/)中初始化。例：

```java
class Example{  
   //static blank final variable  
   static final int ROLL_NO;
   static{ 
      ROLL_NO=1230;
   }  
   public static void main(String args[]){  
      System.out.println(Example.ROLL_NO);  
   }  
}
```

**输出：**

```java
1230
```

## 2）`final`方法

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

例：

```java
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`方法而不会出现任何问题。让我们来看看这段代码：这个程序运行正常，因为我们没有[覆盖](https://beginnersbook.com/2014/01/method-overriding-in-java-with-example/)`final`方法。这表明`final`方法可以[继承](https://beginnersbook.com/2013/05/java-inheritance-types/)，但它们不符合覆盖的条件。

```java
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();  
   }  
}
```

**输出：**

```java
XYZ Class Method
```

## 3）`final`类

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

```java
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();
   }  
}
```

**输出：**

```java
The type ABC cannot subclass the final class XYZ
```

**要记住的要点：**

1）[构造函数](https://beginnersbook.com/2013/03/constructors-in-java/)不能被声明为 final。

2）本地`final`变量必须在声明期间初始化。

3）[接口](https://beginnersbook.com/2013/05/java-interface/)中声明的所有变量默认为 final。

4）我们无法改变`final`变量的值。

5）`final`方法不能被覆盖。

6）`final`类不被继承。

7）如果方法参数被声明为`final`，则不能更改这些参数的值。

8）以所有大写字母命名`final`变量是一个好习惯。

9）`final`，[`finally`](https://beginnersbook.com/2013/04/java-finally-block/ )和`finalize`确定了三个不同的术语。`finally`用于异常处理，`finalize`是在[垃圾收集](https://beginnersbook.com/2013/04/java-garbage-collection/)期间由 JVM 调用的方法。