Java final关键字

原文:https://www.studytonight.com/java-examples/java-final-keyword

final 关键字用于对 Java 中的变量、方法或类进行一些限制。如果一个实体被标记为最终的,那么我们将来就不能改变它的属性。它为不同的实体服务于不同的目的。

在本教程中,我们将学习如何在 Java 中使用 final 关键字。

最终变量

  • 如果一个变量被标记为最终变量,那么我们不能给它重新分配一个值。
  • 变量将始终具有与初始化时相同的值。
  • 如果我们试图进行任何修改,我们将会得到一个编译错误。
  • 最终变量用于在程序中定义一个常量值,在程序执行过程中不应改变。
public class Demo
{
    public static void main(String[] args)
    {
        final int num = 10;
        num = 500;//Compilation error
    }
}

线程“main”Java . lang . error:未解决的编译问题: 最终的局部变量 num 无法赋值。它必须是空白的,并且不能在 Demo.main(Demo.java:6)使用复合赋值

  • 如果一个最终变量已经声明但没有初始化,那么它被称为空白最终变量

  • 静态字段也可以成为最终字段。它们必须在声明时或在静态块中初始化。类常量总是大写的。下划线用于分隔多个单词。

final static double PI = 3.1415;//Declaring and Initializing a final static variable

final static int BOILING_POINT;//Declaring
static { BOILING_POINT = 100; }//Initializing in Static block

最终参考变量

  • 就像最终的基元变量一样,最终引用变量在初始化后不能被重新分配。
  • 但是,我们可以更改被引用对象的属性或字段。

例如,在下面的代码中,我们已经创建了最终的学生类引用变量。我们不能使引用变量指向一个新对象。

class Student
{
    String name;

    Student(String s){
        this.name= s;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

public class Demo
{
    public static void main(String[] args)
    {
        final Student student = new Student("Justin");
        student = new Student("Jessica");//Error because of reassignment
    }
}

线程“main”Java . lang . error:未解决的编译问题: 最终的局部变量 student 无法赋值。它必须是空白的,并且不能在 Demo.main(Demo.java:23)使用复合赋值

但是,我们可以更改对象的名称字段。

public class Demo
{
    public static void main(String[] args)
    {
        final Student s = new Student("Justin");
        s.setName("Justin Greene");//Modifying final object properties is allowed
        System.out.print("Name of Student: " + s.getName());
    }
}

学生姓名:贾斯汀·格林

请注意,上述情况也适用于数组,因为数组也作为对象存储。下面的代码演示了这一点。

final int[] intArr = {1, 2, 3};
intArr = new int[5]; //Error as reassignment is not allowed
intArr[1] = 10; //Allowed

最终参数或参数

我们不能修改方法体内的一个最终参数。我们会得到一个编译错误。

public class Demo
{
    public static void someMethod(final int num)
    {
        num = 10;//Error
        //...
    }
    public static void main(String[] args)
    {
        someMethod(10);
    }
}

线程“main”Java . lang . error:未解决的编译问题: 最终的局部变量 num 无法赋值。在 Demo.someMethod(Demo.java:5)和 Demo.main(Demo.java:10)中,它必须为空,并且不使用复合赋值

期末班

  • 如果一个类被标记为最终类,那么它不能被任何其他类继承
  • 很多核心 Java 库都包含最终类。像整数或双精度这样的包装类是最终的。String类也被声明为最终类。这样做是为了避免继承,以保持类的行为可预测。
  • final 关键字也用于创建不可变的类。
  • 请注意,使类成为最终类不允许任何其他开发人员扩展或添加特性。我们将失去该类的可扩展性和可继承性。

下面的代码显示了最后一个类,如果 ClassB 试图扩展 ClassA,我们将得到一个编译错误。

final class ClassA{
    int a;

    ClassA(int x){
        this.a = x;
    }

    public int getA() {
        return a;
    }

    public void setA(int a) {
        this.a = a;
    }
}

class ClassB extends ClassA//Error
{
    //...
}

请注意,使类成为最终类不会改变类成员的可变性。我们仍然可以改变它们。

final class ClassA{
    int a;

    ClassA(int x){
        this.a = x;
    }

    public int getA() {
        return a;
    }

    public void setA(int a) {
        this.a = a;
    }
}

public class Demo
{
    public static void main(String[] args)
    {
        ClassA classA = new ClassA(10);
        System.out.println("Before: " + classA.getA());
        classA.setA(15);//Allowed
        System.out.println("After: " + classA.getA());
    }
}

10 点前 15 点后

最终方法

  • 我们也可以将方法声明为 final。最终方法不能被覆盖
  • 许多核心 java 库使用最终方法。像 getClass()、notifyAll()、wait()等方法。在对象类中被定义为最终的。
  • 当我们只想限制类方法的覆盖时,Final 方法是 final 类的一个很好的替代方法。
  • 尽管每个 Java 类都扩展了 Object 类,但是没有其他类可以覆盖上面提到的最终方法。这样做是为了确保对象的行为一致。

例如,在下面的代码中,子类不能覆盖最终的 printA()方法。

class ClassA{
    int a;

    ClassA(){
        this.a = 100;
    }

    final void printA()
    {
        System.out.print("Class A or a Subclass of A");
    }
}

class ClassB extends ClassA
{
    int b;

    ClassB(){
        super.a = 150;
        this.b = 200;
    }

    @Override
    void printA()//Error
    {
        System.out.print("Class B");
    }
}

然而,在上面的代码中,最终的方法是由 ClassB 继承的。我们可以在 ClassB 的对象上使用 printA()方法。

class ClassA{
    int a;

    ClassA(){
        this.a = 100;
    }

    final void printA()
    {
        System.out.print("Class A or a Subclass of A");
    }
}

class ClassB extends ClassA
{
    int b;

    ClassB(){
        super.a = 150;
        this.b = 200;
    }
}
public class Demo
{
    public static void main(String[] args)
    {
        ClassB classB = new ClassB();
        classB.printA();
    }
}

甲类或甲亚类

摘要

final 关键字可以应用于变量、方法和类。我们不能修改或重新分配最终变量的值。最终方法不能在任何子类中被覆盖。最终类不能有任何子类。在本教程中,我们学习了如何使用 final 关键字对 Java 中的变量、方法和类进行某些限制。