On the final keyword in Java reprint

Speaking final keyword, presumably a lot of people are not familiar with, when using anonymous inner classes may often use the final keyword. In addition, Java in String class is a final class, so today we have to understand the use of the final keyword. Here is an outline of this directory:

  The basic usage of a keyword .final

  II. In-depth understanding of the final keyword

  If not correct place, a lot of understanding and please correct me.

  Original link:

  http://www.cnblogs.com/dolphin0520/p/3736238.html

The basic usage of a keyword .final

  In Java, final keyword can be used to decorate classes, methods and variables (including members and local variables). Here's a look at these three aspects of the basic usage final keyword.

  1. Modified class

  When modifying a class with a final, indicating that this class can not be inherited. That is, if a class you never let him be inherited, can be modified with final. The final class member variables can be set final necessary, but be aware that all members of the methods are final class are implicitly designated as the final method.

  When using the modified final class, pay attention to careful selection, unless the class is really in the future will not be used for safety reasons, or inheritance, try not to type design for the final class.

  2. modification methods

  The following excerpt "Java programming ideas", Fourth Edition, page 143:

  "There are two reasons for using final approach first reason is that the locking method to prevent any inheriting class to modify its meaning; second reason is efficiency in an early version of Java implementation, the method will be final turn. embedded call. However, if the method is too large, you may not see any performance improvements brought about calls embedded in the recent versions of Java do not need to use these methods to optimize the final. "

  Therefore, if only want to explicitly prohibit this method before the method is set in a subclass case covered as final.

  Note: private class methods implicitly designated as the final method.

  3. modified variables

  Modifying variables are the most content with the final place, but also the rest of this article to be focuses of. First look at the basic syntax final variable:

  For a final variable, if the basic data types of variables, then its value can not be changed once after the initialization; if it is a reference type variable, then after its initialization will not allow its point to another object.

  for example:

  

  The above piece of code, the re-assignment of the variable i and obj are being given.

II. In-depth understanding of the final keyword

  After learning the basic usage of the final keyword, in this section we look at the final keyword confusing place.

1. The final class variables and common variables What is the difference?

  When applied to a final class member variables, member variables (note that the class member variables, local variables only need to be assigned to the initialized before use) must be defined or initialized at the time of the assignment in the constructor, and the final variable Once the assignment is initialized, it can not be assigned up.

  So what difference does it make final variables and common variables in the end? See the following example a:

1
2
3
4
5
6
7
8
9
10
11
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));
     }
}

  

  View Code

  You can first think about the output of this question. Why the first comparison is true, and the second comparison is fasle. There is the difference between final variables and variables of the ordinary, when the final variable is the basic data types and String type, if we can know its exact value during compilation, the compiler will use it as a compile-time constants. That is used in place of the final variable, the equivalent of direct access to the constant need not be determined at run time. This macro substitution and C language a bit like. Thus a piece of code in the above, since the variable b is final modification, so as compiler constants are so used to place the variable b, b directly replace its value. As for the variable d you need to access it through a link at runtime. Surely we should understand the difference between them, but to pay attention only during compilation can know exactly the case of final value of the variable, the compiler will perform this optimization, such as the following code will not be optimized:

1
2
3
4
5
6
7
8
9
10
11
12
13
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" ;
     }
}

  The output of this code to false.

2. the final modified object reference variables pointing to the contents of variable it?

  In the above-mentioned are final modified reference variable initialization assignment once can no longer point to other objects, then the reference point of the contents of the variable object variable it? Look at the following example:

1
2
3
4
5
6
7
8
9
10
11
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 ;
}

  This code can be successfully compiled by the output result and outputting a result. This shows that after the modified reference variable is final, although it can not point to other objects, but the content it points to the object is variable.

3.final and static

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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();
}

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

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

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

5.关于final参数的问题

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

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

  看这个例子就清楚了:

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

  再看下面这段代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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" );
     }
}

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

  所以关于网上流传的final参数的说法,我个人不是很赞同。

参考资料:

  《Java编程思想》

Guess you like

Origin www.cnblogs.com/ncwoniu/p/11498312.html