1. 程式人生 > >java中的修飾符final和static

java中的修飾符final和static

1.final 修飾類時表明該類不能被繼承,自然類中的方法預設是final型的。

2.final 修飾方法時不允許被子類覆蓋,也就是可以被繼承。一個final類中,一個final方法只能被實現一次。

public class Test1 {
      public final void show(){
    	  System.out.println("this is super class");
      }
}

上面作為下面類的父類使用。
public class Test extends Test1 {
//	public void show(){   //這裡如果企圖重寫覆蓋父類中final修飾的方法會報錯。
//		
//	}
        public static void main(String[] args){
           Test t=new Test();
           t.show();
        }
}

3.final 修飾的成員變數只能被賦值一次。如果是引用型別的變數,則不能讓該變數再去指向其他物件。

                Object a=new Object();
        	final Object  b=a; //b為a的引用變數,當改變b的指向時,如下一行會報錯
        	b=new Object();  //報錯

如果所指的變數重新賦值會出現什麼情況呢,如下面中的a變化時,b會如何呢?

public static void main(String[] args){
           int a=1;
           final int b=a;
          System.out.println(a);
          System.out.println(b);
            a=2;
            System.out.println(a);
            System.out.println(b);  //這裡的b其實還是指代最初的1,總之記住一句話,一旦b被初始化,則不能改變。

Final類中的成員變數只要沒有新增final修飾都可以照常操作。如

public final class Test {
	     int   a=3;
        public static void main(String[] args){
          Test b=new Test();
          b.a=4; //如果a新增final修飾則會報錯
        System.out.println(b.a); //這裡輸出值為4.
        }
}

final在修飾類中成員變數時可以不給初值,但是必須保證在使用前初始化。儘管如此,這也提供了很大的靈活性。儘管初始化之後不能再改變,但通過建構函式,我們可以讓final變數依據使用物件而改變。如下:

public class Test1 {
	public final int a; //這裡宣告的final型變數可以不賦值,但是必須給出一個類似的建構函式,不能使用普通方法賦值。如果子類繼承該類則必須在構造方法中給出一個<span style="font-family: Arial, Helvetica, sans-serif;"> //確定的值。這都是因為final型別變數必須在使用之前初始化。</span>
	public Test1(int a){
		this.a=a;
	}
}

4,final 引數。

傳遞的實引數如果是final 型,而形參不要求則很容易理解。形參的改變與實參無關。如果需要傳遞的形參是final型,則試圖改變形參值。會出錯。

public class Test1 {
	    public void show(final int i){
	    	i++;//這裡會報錯,提示形參不能重新賦值。
	}
	public static void main(String[] args){
		(new Test1()).show(3);
	}
	
}
對於博文http://www.cnblogs.com/dolphin0520/p/3736238.html中認為“當你在方法中不需要改變作為引數的物件變數時,明確使用final進行宣告,會防止你無意的修改而影響到呼叫方法外的變數”不當,並舉了幾個例子。我去搜查了一下,發現JDK中有這樣一句話:Once a final variable has been assigned, it always contains the same value. If a final variable holds a reference to an object, then the state of the object may be changed by operations on the object, but the variable will always refer to the same object.----取自博文http://blog.csdn.net/zhengqiqiqinqin/article/details/14497479。這句話翻譯過來應該是如果final修飾的變數一旦被賦值,則不允許改變。如果final修飾的變數是對某物件的引用,則該變數會一直指向物件,但是該物件的狀態可以改變。換句話說如果final修飾的是int ,double,byte,char等基本資料型別,一旦賦值不可改變。如果修飾的是某類物件如StringBuffer,Date型則變數會一直指向該變數,但該物件中的內容可以改變,如下:
public class Test1 {
	  
	  public void show (final Test test){  
		  test.i++;               //這裡不會報錯
		  System.out.println(test.i);
	
	}
	public static void main(String[] args){
		Test t=new Test();   //這裡Test是另外一個類,類中我給的i值為一,傳過去之後可以看到輸出的值為2;
		(new Test1()).show(t);
	}
}

遇到final時請記住一句話一旦被賦值則不可另外再改變。如果final修飾變數指向物件,則物件中的成員變數可以改變,只不過final在這裡的作用就好像把變數當成了一個標籤貼在了特定的盒子上,至於盒子裡的內容不管,可是如果你想把標籤撕下貼到其他同類型的盒子上,那就要出錯了。

static

static主要作用就是在不建立物件的情況下,通過類名來訪問類中的靜態方法和靜態成員變數。

1.static修飾方法。

   static修飾的方法中不得含有非靜態的方法和非靜態的變數。因為非靜態的方法和變數通常是和物件繫結在一塊的。而static方法是和物件無關。

  static修飾的變數,不會影響到物件訪問許可權(方法也是),靜態變數和類繫結只存在一個副本,而那些和物件繫結的變數則因為物件不同,可以存在多個副本也不會衝突。

static修飾模組。通常static修飾模組主要作用就是優化程式效能,就是速度快一些之類的意思。

總之,static 就是告訴計算機某個變數或方法或程式碼塊你只給我留一份就行,任何該類的物件都得共享這一塊。由於凡是static 修飾的都只加載一次,尤其當物件較多頻繁使用某一塊程式碼時,新增static修飾,程式效能會優很多。

關於static的詳細解釋參看http://www.cnblogs.com/dolphin0520/p/3799052.html。

對於static、final共同修飾的變數方法有兩層含義,可以通過類直接訪問;不能改變其值或覆蓋。在訪問上,可以通過非靜態方法,物件訪問靜態變數方法,但是不建議還是用類好一些。

本文主要參考的文章除了以上提到的外還有http://lavasoft.blog.51cto.com/62575/18771/,這裡也是講的static和final區別。本文系自己讀了很多牛人寫的之後感想製作。僅作交流,如果不當,敬請留言討論。一塊學習,共同提高。