The use of final in Java

Posted by Hitwalker on Wed, 09 Mar 2022 17:57:13 +0100

Original link https://www.cnblogs.com/dolphin0520/p/10651845.html

Author Matrix Haizi

This article is a note

0. General

Like static, final is a modifier. Final is used to modify classes, methods and variables (including local variables and member variables).

1. final modifier class

The class modified by final indicates that it cannot be inherited, and all member methods in the class will be implicitly modified as final.

Generally, the class is not defined as final.

2. final modification method

It indicates that the functions provided by this method have met the current requirements, do not need to be extended, and any class inherited from this class is not allowed to override this method.

However, inheritance can still inherit this method, that is, the method modified by final can be used directly. In a declaration class, a final method is implemented only once.

That is, only methods that explicitly do not want to be overwritten will be modified as final.

The private method of the class is implicitly specified as the final method.

3. final modifier variable

  • If the modified variable is a basic data type, the value of this variable will not be changed.
  • If the modified variable is a reference type, the variable cannot point to other objects after initialization, but the value of the object pointed to can be changed.

3.1 final modifier member variable

When final modifies a member variable, you must ensure that the member variable is assigned when it is declared or in the constructor, and once initialization is completed, the value cannot be changed.

There are the following codes

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
*/

The result here contains the characteristics of final: when final modifies the basic data type and String, if the compiler can know the value of this variable, the compiler will use it as a compile time constant, similar to the macro in C. So at this time, a and C actually point to the same reference, while e points to a new reference.

However, the premise of this feature is to know the specific value during compilation, as shown below

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

When the above code is actually running, b can be initialized by calling the getHello function, so the value cannot be obtained during compilation, so the result is false.

3.2 final modifier local variable

Note that Java uses value passing, so pay attention to it when calling. for example

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

The above code will report an error because i is recognized as a local variable in the body of the changeValue function. The variable is final and the value of i cannot be changed.

4. final and static

When decorating member variables, final is guaranteed to be immutable, and static means that each object has a copy.

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 is modified as final, which means immutable, while J means that all objects share the same J, so i is different and j is the same.