final的用法

一. final 数据

对于final修饰的数据,有以下两种情况:

1. 一个永不改变的编译常量

   1: public class FinalTest{
   2:     private final static int VALUE = 1;
   3: }

对于编译常量,编译器可以在编译期常量的值,减轻运行时的负担。其中,static强调只有一份,而final强调它是一个常量。在Java中,这类常量必须是基本数据类型,并且在对这个常量进行定义的时候,必须对其赋值。

2. 一个在运行时被初始化的值,而你不希望它被改变

(1)final修饰基本数据类型

   1: public class FinalTest{
   2:     private final  int  value = 1;
   3:     public void test(int n){
   4:         value = n;        //The final local variable s cannot be assigned. It must be blank and not using a compound assignment 
   5:     }
   6: }

对于final修饰的基本数据类型,final使其数据保持恒定不变,如上所示,value的值只能为1,不能被修改。

(2) final修饰引用类型

   1: public class FinalTest{
   2:     private final TreeNode root = new TreeNode(1);
   3:     public void test(){
   4:         root = new TreeNode(2)  //error
   5:         root.val = 2;              //OK
   6:     }
   7: }
   8: class TreeNode{
   9:     private int val;
  10:     TreeNode left;
  11:     TreeNode right;
  12:     TreeNode(int val){
  13:         this.val = val;
  14:     }
  15: }

final保证引用对象的地址恒定不变,即无法把他指向另一个对象,但是final修饰对象的本身是可以改变

二 final 参数

java允许在参数列表中以声明的方式将参数指明为final,表示在方法内部你无法更改参数所引用的对象。

   1: public class FinalTest{
   2:     public void test1(final TreeNode root){
   3:         root = new TreeNode(2)  //error
   4:     }
   5:  
   6:     public void test2(TreeNode root){
   7:         root = new TreeNode(2)    //OK 
   8:     }
   9: }
  10: class TreeNode{
  11:     private int val;
  12:     TreeNode left;
  13:     TreeNode right;
  14:     TreeNode(int val){
  15:         this.val = val;
  16:     }
  17: }

这一特性主要用于向匿名内部类传递参数

如果你定义了一个匿名内部类,并且希望它使用一个在其外部定义的对象,那么编译器会要求参数引用参数是final的。

   1: public class FinalTest{
   2:     public Class1 test1(final String str){
   3:         return new Class1(){
   4:             private String label = str;
   5:         }
   6:     }
   7:  
   8:     public Class2 test2(String str){
   9:         return new Class2(){
  10:             public void f(){
  11:                 System.out.println("anonymous");
  12:             }
  13:         }
  14:     }
  15:  
  16: }

对于匿名内部类Class1,因为其需要引用外部的对象str,所以需要将引用的参数用final,而对于匿名内部类Class2,它不需要引用外部的变量,所以不需要用fina修饰。

三. 空白final

空白final是指被声明为final但又未给定初值的域。无论什么情况,编译都要确保空白final在使用前都要被初始化

   1: public class FinalTest{
   2:     private final int i = 0;     //Initialized final
   3:     private final int j;         // Blank final
   4:  
   5:     public FinalTest(){
   6:         j = 1; // 初始化空白final
   7:     }
   8:  
   9:     public FinalTest(int x){
  10:         j = x;  // 初始化空白final
  11:     }
  12: }

 

四 final的总结

1. final类不能被继承,也就是其没有子类,final中的方法默认为final方法

2. final方法不能被子类的方法覆盖,但是可以被继承

3. final不能用来修饰构造函数

posted @ 2015-12-19 18:57  bloodHunter  阅读(294)  评论(0编辑  收藏  举报