I have something to say about some details of final -- in-depth understanding of final

Posted by Hopps on Mon, 29 Nov 2021 03:06:00 +0100

There are thousands of people in the vast sea. Thank you for seeing here this second. I hope my article will help you!

May you keep your love and go to the mountains and seas in the future!

Caption: as for the final keyword, it is also a keyword we often use. It can be modified on classes, variables and methods. From this point of view, we can define some of its immutability!

Like the String class we often use, it is a class modified by final, and its character array is also modified by final. But have you really understood some details of final?

Starting from this article, I will take you to understand the details of final!

😚 In depth understanding of final

We all know about the characteristics and basic use of final, but have you really understood the details of final? When the interviewer asks you, can you say something different about final?

Don't panic! Now let's fill in some details of final immediately, and add the necessary knowledge, water blowing and interview! Drive!

😜 Gain insight into modifier variables

In Java, variables can be divided into member variables and method local variables.

For member variables, they can be divided into class variables (static variables) and instance variables.

The final keyword will be slightly different in details when modifying different types of variables. Let's take a look at the details!

ðŸĨ° Decorated member variable

For each Java class, its member variables can be divided into class variables (static variables) and instance variables. For different variables, in fact, their initialization and assignment time is slightly different!

  • Class variable:

    1. You can directly initialize the assignment operation when declaring variables

    2. You can also initialize and assign class variables in static code blocks

  • Instance variable:

    1. You can directly initialize the assignment operation when declaring variables
    2. You can also initialize and assign instance variables in non static code blocks
    3. You can also initialize and assign instance variables in the constructor
  • be careful:

    1. No matter when the initialization assignment operation is carried out, there must be an initialization assignment operation in the end, otherwise an uninitialized error during compilation will be thrown!
    2. After final modifies the member variable, no matter what time it is initialized and assigned, it can no longer be assigned.

Let's meet each other in the specific code. I can't understand it. Let's use the code!

Class variable:

package com.nz.test;

/**
 * Detailed explanation of modification class variable operation
 */
public class ClassVariableFinalTest {

    // Define a class variable, that is, a static variable
    // 1. You can directly initialize the assignment operation when declaring variables
    private final static int classVariable = 0;

    // 2. You can also initialize and assign class variables in static code blocks
    private final static int classVariable2;
    
    // But if you don't write this, classVariable2 will report an uninitialized exception!
    static {
        classVariable2 = 0; 
        
        // After the classVariable is initialized, the value cannot be modified!
        classVariable = 1; // Compilation error
    }
}

It can be seen that when we initialize and assign class variables, we can assign values to two different machines at the same time! But the final feature will still exist! For example, if it is not initialized, the value cannot be modified after initialization!

Instance variable:
Next, let's look at different times in the instance variable!

package com.nz.test;

/**
 * Detailed explanation of modification instance variable operation
 */
public class InstanceVariableFinalTest {

    // Define instance variables
    // 1. You can directly initialize the assignment operation when declaring variables
    private final int instanceVariable = 0;

    // 2. You can also initialize and assign class variables in the code block
    private final int instanceVariable2;

    // 3. You can also initialize and assign instance variables in the constructor
    private final int instanceVariable3;

    // But if you don't write this, instanceVariable2 will report an uninitialized exception!
    {
        instanceVariable2 = 0;

        // After the instanceVariable is initialized, the value cannot be modified!
//        instanceVariable = 1; //  Compilation error
    }

    public InstanceVariableFinalTest(){
        // But if you don't write this, instanceVariable3 will report an uninitialized exception!
        instanceVariable3 = 0;
    }
}

You can see that when we initialize and assign instance variables, we can assign values to three different machines at the same time! But the final feature will still exist! For example, if it is not initialized, the value cannot be modified after initialization!

ðŸĪŠ Modify local variables

Local variables are declared in methods, construction methods or statement blocks;

Characteristics of modified local variables:

  • When final modifies a local variable, if the local variable has been initialized and assigned, the local variable cannot be changed again later.
  • If the final modified local variable is not initialized, it can be assigned. If it is assigned only once, once it is assigned again, an error will occur.

We still continue to meet with code. Only by looking at it can we have a deeper understanding!

For a variable, it can be decorated with two data types: reference type and basic data type. Next, we will elaborate on these two types.

Basic data variables:

Let's see if final is really the same as the above features when it modifies basic data type variables.

package com.nz.test;

/**
 * Detailed explanation of modified local variable operation
 */
public class LocalVariableFinalTest {

    // Test local variables
    public void localVariableTest(){
        // Defining basic data type variables
        final int localVariable;

        // You can see that if we do not initialize, there will be no compile time error
        // However, if you reference without initialization, an uninitialized error will be reported.
        System.out.println("localVariable = " + localVariable);
        
        // Perform initialization assignment
        localVariable = 1;
        
        // Once the initialization operation is performed, the assignment operation can no longer be performed
        localVariable = 2;
    }
}

We can find that if we define a final local variable, we find two problems:

  1. We don't need to initialize the assignment operation and there will be no error. However, you can't reference it when there is no initialization assignment operation, because it has no default value, so you must initialize the assignment operation before you can reference it.
  2. In the local variable modified by final, if and only once assigned, once assigned again, there will be an error. This is the same as the error of modifying the member variable before!

Reference type variable:

Through the above basic data type case, we found that once the basic data type variable modified by final is initialized and assigned, another assignment will make an error. This means that variables of basic data types can no longer be modified. What about reference type variables? Can it change? Next, let's have a look!

package com.nz.test;

/**
 * Detailed explanation of modified local variable operation
 */
public class LocalVariableFinalTest {

    // Under the method just adopted, note out any errors!
    
    // Test reference type local variable
    public static void main(String[] args) {

        // Defining a basketball player -- LeBron James
        final BasketballPlayer james = new BasketballPlayer(36, "Lebron James");

        // Next, we will carry out a series of operations on it!
        // 1. Reinitialize the assignment—— As you can see, reference type variables cannot be re assigned
        // If you want to compile, you have to comment it out here!
//        James = new basketball player (36, "old emperor!");

        // 2. Re assign the parameters in james
        james.setName("Sunset red team captain!");

        // You can see that there is no error! Let's try printing it to see if the name is LeBron James or the captain of the sunset red team?
        System.out.println("james = " + james.getName());

    }
}

// Define a basketball player
class BasketballPlayer {

    // Name age attribute
    private int age;
    private String name;

    // Design a parametric structure
    public BasketballPlayer(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public String getName() {
        return name;
    }

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

Results obtained:

james = Sunset red team captain!

We can find two problems:

  1. If we want to re initialize and assign the final reference type variable, we will also report an error to you, because once the reference type variable modified by final is initialized and assigned, the object it points to is immutable, and your new operation is to re assign a new address, of course not!
  2. When we want to modify the parameters in the reference type, that is, we change the name attribute in the reference type variable james modified by final to the sunset red team leader, we can modify it successfully! Although the above reference address cannot be changed, the object properties under this address can be changed!

Summary:

Once the reference type variable modified by final is initialized and assigned, the object it points to is immutable, but the properties of the object are mutable!

😘 In depth understanding of modification methods

From the basic use, we know that the method modified by final can not be rewritten, so can overloading?

What, you don't know the difference between overloading and rewriting?

rewrite:

Let's take another look at Rewriting:

package com.nz.test;

/**
 * Test the final modification method!
 * This class is the parent class. When the child class inherits this class, see whether the final method can be overridden
 */
public class MethodFinalTest {

    // final modifier saySomething() method
    public final String saySomething(){
        return "What do you want to say, Lakers championship!!!";
    }

    // The talkSomething() method is not modified by final
    public String talkSomething(){
        return "What do I want to say, the old sunset is red, hurry up and make it red!!!";
    }
}

// Define subclasses that inherit the MethodFinalTest method
class MethodSun extends MethodFinalTest{

    // First, see if you can override the talkSomething() method that is not modified by final
    public String talkSomething(){
        return "I can only agree with you that the old sunset is red. Hurry up and make it red!!!";
    }

    // Next, see if you can override the saySomething() method modified by final
//    public String saySomething(){
//        return "I can only agree with you, Lakers championship!!!";
//    }
}

We can see that we cannot rewrite the method modified by final.

Overload:
What about overloading? Shall we overload the saySomething method in the MethodFinalTest class?

public class MethodFinalTest {

    // final modifier saySomething() method
    public final String saySomething(){
        return "What do you want to say, Lakers championship!!!";
    }

    // final modifier saySomething() method
    public final String saySomething(String name){
        return "I only say five words, Lakers championship!!!" + name;
    }

    // The talkSomething() method is not modified by final
    public String talkSomething(){
        return "What do I want to say, the old sunset is red, hurry up and make it red!!!";
    }
}

It can be seen that the method modified by final has no resistance to overloading and can be overloaded.

😙 Learn more about decorating classes

From the basic usage, we know that the classes modified by final can not be inherited, so we will use the final keyword for those classes? In this way, what scene can be used!

For a class, it can be inherited by its subclasses, overridden the methods in its parent class or changed the properties of its parent class, which will lead to certain security risks. For example, your current capital fund has 100W, and you will spend about 1000 every day, but because you can be inherited, the effect of your capital loss is accelerated, resulting in your capital insecurity!

(for me, I don't seem to have such a problem! I only have a few dollars???)

So for security, it's our point to consider! If a class does not want to be inherited, we can use final to modify it.

For the String class we often use, it is modified by final. The main reason is security, because once you can inherit it and rewrite the methods in it, the whole system may be abnormally unsafe. In addition, in order to be efficient, and when only the String is immutable, we can realize the String constant pool. The String constant pool can cache the String for us and improve the running efficiency of the program.

ðŸŒļ summary

I believe all of you have a better understanding of the keyword final. When we expand our knowledge stack, we are also discovering our shortcomings, right. We still have a handful of things waiting for us to explore and explore! I hope you will study with the purpose of analyzing problems, which will certainly be of great help to your own development in the future! Let's continue to look forward to the content of final in the next chapter! Welcome to the next chapter!

Let's cheer together! I am not talented. If there are any omissions and mistakes, I also welcome criticism and correction in the comments of talent leaders! Of course, if this article is sure to be of little help to you, please also give some praise and collection to the kind and lovely talent leaders. Thank you very much!

Learn here, today's world is closed, good night! Although this article is over, I am still there and will never end. I will try to keep writing articles. The future is long. Why are you afraid of cars and horses!

Thank you for seeing here! May you live up to your youth and have no regrets!

Topics: Java final