Home > Backend Development > PHP Tutorial > Detailed explanation of final keyword in Java_php skills

Detailed explanation of final keyword in Java_php skills

WBOY
Release: 2016-05-16 20:08:39
Original
1293 people have browsed it

Speaking of the final keyword, many people must be familiar with it. The final keyword may be often used when using anonymous inner classes. In addition, the String class in Java is a final class, so today we will learn about the usage of the final keyword.
Main introduction: 1. Basic usage of final keyword. 2. Deeply understand the final keyword

1. Basic usage of final keyword

In Java, the final keyword can be used to modify classes, methods and variables (including member variables and local variables). Let’s learn about the basic usage of the final keyword from these three aspects.

 1. Modification class

When a class is modified with final, it indicates that this class cannot be inherited. In other words, if you will never let a class be inherited, you can modify it with final. Member variables in a final class can be made final as needed, but be aware that all member methods in a final class will be implicitly designated as final methods.

When using final to modify a class, you should choose carefully. Unless this class really will not be used for inheritance in the future or for security reasons, try not to design the class as a final class.

2. Modification methods

The following passage is excerpted from page 143 of the fourth edition of "Java Programming Thoughts":

"There are two reasons for using final methods. The first reason is to lock the method to prevent any inherited class from modifying its meaning; the second reason is efficiency. In early Java implementation versions, final Methods are converted to inline calls. However, if the method is too large, you may not see any performance improvement from inline calls. In recent Java versions, there is no need to use final methods for these optimizations. "

Therefore, set a method to final only if you want to explicitly prevent the method from being overridden in subclasses.

Note: Private methods of a class are implicitly designated as final methods.

 3. Modify variables

Modifying variables is the most commonly used place for final, and it is also what this article will focus on next. First, let’s understand the basic syntax of final variables:

For a final variable, if it is a variable of a basic data type, its value cannot be changed once it is initialized; if it is a variable of a reference type, it cannot point to another object after it is initialized.

For example:

 

In the above piece of code, errors are reported when reassigning variables i and obj.

2. In-depth understanding of final keywords

After understanding the basic usage of the final keyword, in this section we will take a look at the areas where the final keyword is easily confused.

1. What is the difference between final variables and ordinary variables of a class?

When using final to act on a member variable of a class, the member variable (note that it is a member variable of the class, local variables only need to ensure that they are initialized and assigned before use) must be initialized and assigned at the time of definition or in the constructor. Moreover, once a final variable is initialized and assigned a value, it cannot be assigned a value again.

 So what is the difference between final variables and ordinary variables? Please see an example below:

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));
  }
}
Copy after login

true
false

You can first think about the output result of this question. Why the first comparison result is true and the second comparison result is fasle.

This is the difference between final variables and ordinary variables. When the final variable is a basic data type or String type, if its exact value can be known during compilation, the compiler will use it as a compile-time constant. That is to say, where the final variable is used, it is equivalent to direct access to the constant and does not need to be determined at runtime. This is somewhat similar to macro substitution in C language.

So in the above piece of code, since the variable b is modified as final, it will be treated as a compiler constant, so where b is used, the variable b will be directly replaced with its value. However, access to variable d needs to be done through the link at runtime.

I think everyone should understand the difference, but please note that the compiler will only perform such optimization if the value of the final variable can be accurately known during compilation. For example, the following code will not be optimized :

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";
  }
}
Copy after login

 The output result of this code is false.

2. Is the content of the object pointed to by the reference variable modified by final mutable?

As mentioned above, the reference variable modified by final cannot point to other objects once it is initialized and assigned. So, is the content of the object pointed to by the reference variable mutable? Look at this example:

public class Test {
  public static void main(String[] args) {
    final MyClass myClass = new MyClass();
    System.out.println(++myClass.i);
  }
}
class MyClass {
  public int i = 0;
}
Copy after login

  这段代码可以顺利编译通过并且有输出结果,输出结果为1。这说明引用变量被final修饰之后,虽然不能再指向其他对象,但是它指向的对象的内容是可变的。

3.final和static

  很多时候会容易把static和final关键字混淆,static作用于成员变量用来表示只保存一份副本,而final的作用是用来保证变量不可变。看下面这个例子:

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();
}
Copy after login

  运行这段代码就会发现,每次打印的两个j值都是一样的,而i的值却是不同的。从这里就可以知道final和static变量的区别了。

4.匿名内部类中使用的外部局部变量为什么只能是final变量?

  这个问题请参见上一篇博文中《Java内部类详解》中的解释,在此处不再赘述。

5.关于final参数的问题

  关于网上流传的”当你在方法中不需要改变作为参数的对象变量时,明确使用final进行声明,会防止你无意的修改而影响到调用方法外的变量“这句话,我个人理解这样说是不恰当的。

  因为无论参数是基本数据类型的变量还是引用类型的变量,使用final声明都不会达到上面所说的效果。

  看这个例子就清楚了:

  上面这段代码好像让人觉得用final修饰之后,就不能在方法中更改变量i的值了。殊不知,方法changeValue和main方法中的变量i根本就不是一个变量,因为java参数传递采用的是值传递,对于基本类型的变量,相当于直接将变量进行了拷贝。所以即使没有final修饰的情况下,在方法内部改变了变量i的值也不会影响方法外的i。

  再看下面这段代码:

public class Test {
  public static void main(String[] args) {
    MyClass myClass = new MyClass();
    StringBuffer buffer = new StringBuffer("hello");
    myClass.changeValue(buffer);
    System.out.println(buffer.toString());
  }
}
class MyClass {
  void changeValue(final StringBuffer buffer) {
    buffer.append("world");
  }
}
Copy after login

  运行这段代码就会发现输出结果为 helloworld。很显然,用final进行修饰并没有阻止在changeValue中改变buffer指向的对象的内容。

有人说假如把final去掉了,万一在changeValue中让buffer指向了其他对象怎么办。有这种想法的朋友可以自己动手写代码试一下这样的结果是什么,如果把final去掉了,然后在changeValue中让buffer指向了其他对象,也不会影响到main方法中的buffer,原因在于java采用的是值传递,对于引用变量,传递的是引用的值,也就是说让实参和形参同时指向了同一个对象,因此让形参重新指向另一个对象对实参并没有任何影响。

以上内容就是Java中final关键字详解,希望对大家有所帮助。

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template