java的static和this


1>static:靜態修飾符
    static表示“全局”或者“靜態”的意思,用來修飾成員變量和成員方法,也可以形成靜態static代碼塊,但是Java語言中沒有全局變量的概念。
    被static修飾的成員變量和成員方法獨立於該類的任何對象。也就是說,它不依賴類特定的實例,被類的所有實例共享。只要這個類被加載,Java虛擬機就能根據類名在運行時數據區的方法區內定找到他們。因此,static對象可以在它的任何對象創建之前訪問,無需引用任何對象。
    用public修飾的static成員變量和成員方法本質是全局變量和全局方法,當聲明它類的對象時,不生成static變量的副本,而是類的所有實例共享同一個static變量。
 
        
    static變量前可以有private修飾,表示這個變量可以在類的靜態代碼塊中,或者類的其他靜態成員方法中使用(當然也可以在非靜態成員方法中使用--廢話),但是不能在其他類中通過類名來直接引用,這一點很重要。實際上你需要搞明白,private是訪問權限限定,static表示不要實例化就可以使用,這樣就容易理解多了。static前面加上其它訪問權限關鍵字的效果也以此類推。
 
        
 
        
    static修飾的成員變量和成員方法習慣上稱為靜態變量和靜態方法,可以直接通過類名來訪問,訪問語法為:
類名.靜態方法名(參數列表...) 
類名.靜態變量名
 
        
        用static修飾的代碼塊表示靜態代碼塊,當Java虛擬機(JVM)加載類時,就會執行該代碼塊(用處非常大)。
 
        
1、static變量
   按照是否靜態的對類成員變量進行分類可分兩種:一種是被static修飾的變量,叫靜態變量或類變量;另一種是沒有被static修飾的變量,叫實例變量。
兩者的區別是:
   對於靜態變量在內存中只有一個拷貝(節省內存),JVM只為靜態分配一次內存,在加載類的過程中完成靜態變量的內存分配,可用類名直接訪問(方便),當然也可以通過對象來訪問(但是這是不推薦的)。
    對於實例變量,沒創建一個實例,就會為實例變量分配一次內存,實例變量可以在內存中有多個拷貝,互不影響(靈活)。
 
        
2、靜態方法
   靜態方法可以直接通過類名調用,任何的實例也都可以調用,因此靜態方法中不能用this和super關鍵字,不能直接訪問所屬類的實例變量和實例方法(就是不帶static的成員變量和成員成員方法),只能訪問所屬類的靜態成員變量和成員方法。因為實例成員與特定的對象關聯!這個需要去理解,想明白其中的道理,不是記憶!!!
    因為static方法獨立於任何實例,因此static方法必須被實現,而不能是抽象的abstract。
 
        
 
 
        
3、static代碼塊
   static代碼塊也叫靜態代碼塊,是在類中獨立於類成員的static語句塊,可以有多個,位置可以隨便放,它不在任何的方法體內,JVM加載類時會執行這些靜態的代碼塊,如果static代碼塊有多個,JVM將按照它們在類中出現的先后順序依次執行它們,每個代碼塊只會被執行一次。例如:
 
        
 
public class Test5 { 
        private static int a; 
        private int b; 

        static { 
                Test5.a = 3; 
                System.out.println(a); 
                Test5 t = new Test5(); 
                t.f(); 
                t.b = 1000; 
                System.out.println(t.b); 
        } 

        static { 
                Test5.a = 4; 
                System.out.println(a); 
        } 

        public static void main(String[] args) { 
                // TODO 自動生成方法存根 
        } 

        static { 
                Test5.a = 5; 
                System.out.println(a); 
        } 

        public void f() { 
                System.out.println("hhahhahah"); 
        } 
}
 
        

  

 
        
 
 
        
運行結果:3
hhahhahah
1000
4
利用靜態代碼塊可以對一些static變量進行賦值,最后再看一眼這些例子,都一個static的main方法,這樣JVM在運行main方法的時候可以直接調用而不用創建實例。
 
        
2>this:代表當前的對象

一、this關鍵字主要有三個應用:

      (1)this調用本類中的屬性,也就是類中的成員變量;

      (2)this調用本類中的其他方法;

      (3)this調用本類中的其他構造方法,調用時要放在構造方法的首行。

 

Public Class Student 
{ 
    String name; 
    //定義一個成員變量name 
    private void SetName(String name) 
        { 
           //定義一個參數(局部變量)
           name this.name=name; 
           //將局部變量的值傳遞給成員變量 
          } 
}

 

  

 

 

 應用一:引用成員變量

    如上面這段代碼中,有一個成員變量name,同時在方法中有一個形式參數,名字也是name,然后在方法中將形式參數name的值傳遞給成員變量name,雖然我們可以看明白這個代碼的含義,但是作為Java編譯器它是怎么判斷的呢?到底是將形式參數name的值傳遞給成員變量name,還是反過來將成員變量name的值傳遞給形式參數name呢?也就是說,兩個變量名字如果相同的話,那么Java如何判斷使用哪個變量?此時this這個關鍵字就起到作用了。this這個關鍵字其代表的就是對象中的成員變量或者方法。也就是說,如果在某個變量前面加上一個this關鍵字,其指的就是這個對象的成員變量或者方法,而不是指成員方法的形式參數或者局部變量。為此在上面這個代碼中,this.name代表的就是對象中的成員變量,又叫做對象的屬性,而后面的name則是方法的形式參數,代碼this.name=name就是將形式參數的值傳遞給成員變量。這就是上面這個代碼的具體含義。

    一般情況下,在Java語言中引用成員變量或者成員方法都是以對象名.成員變量或者對象名.成員方法的形式。不過有些程序員即使在沒有相同變量的時候,也喜歡使用this.成員變量的形式來引用變量,這主要是從便於代碼的閱讀考慮的。一看到這個this關鍵字就知道現在引用的變量是成員變量或者成員方法,而不是局部變量。這無形中就提高了代碼的閱讀性。不過話說回來,這是this關鍵字在Java語言中的最簡單的應用。從這個應用中,我們可以看出this關鍵字其代表的就是對象的名字。 其實如果是局部變量的話,也是相同的道理。如在上面的代碼中,name不是形式參數,而是一個局部變量。此時Java也會遇到相同的疑惑,即變量名name代表的到底是局部變量還是形式參數?name=name到底代表的是什么含義?根據局部變量的作用域,在方法內部,如果局部變量與成員變量同名的話,那么是以局部變量為准。可是在name=name這個賦值語句中,將局部變量的值賦值給自己,顯然並不是很合適。根據代碼的含義,本來的意思應該是將局部變量賦值給成員變量。為了更清晰的表達這個含義,為此最好采用如下的書寫格式this.name=name。這里的this關鍵字含義就是對象名student,為此this.name就表示student.name

應用二:調用類的構造方法

  

public class Student {
   //定義一個類,類的名字為student。
public Student() 
{
  //定義一個方法,名字與類相同故為構造方法 
    this(“Hello!”); }
 public Student(String name) 
{ //定義一個帶形式參數的構造方法 } 
}

 

  

 

this關鍵字除了可以調用成員變量之外,還可以調用構造方法。在一個Java類中,其方法可以分為成員方法和構造方法兩種。構造方法是一個與類同名的方法,在Java類中必須存在一個構造方法。如果在代碼中沒有顯示的體現構造方法的話,那么編譯器在編譯的時候會自動添加一個沒有形式參數的構造方法。這個構造方法跟普通的成員方法還是有很多不同的地方。如構造方法一律是沒有返回值的,而且也不用void關鍵字來說明這個構造方法沒有返回值。而普通的方法可以有返回值、也可以沒有返回值,程序員可以根據自己的需要來定義。不過如果普通的方法沒有返回值的話,那么一定要在方法定義的時候采用void關鍵字來進行說明。其次構造方法的名字有嚴格的要求,即必須與類的名字相同。也就是說,Java編譯器發現有個方法與類的名字相同才把其當作構造方法來對待。而對於普通方法的話,則要求不能夠與類的名字相同,而且多個成員方法不能夠采用相同的名字。在一個類中可以存在多個構造方法,這些構造方法都采用相同的名字,只是形式參數不同。Java語言就憑形式參數不同來判斷調用那個構造方法。

    在上面這段代碼中,定義了兩個構造方法,一個帶參數,另一個沒有帶參數。構造方法都不會有返回值,不過由於構造方法的特殊性,為此不必要在構造方法定義時帶上void關鍵字來說明這個問題。在第一個沒有帶參數的構造方法中,使用了this(“Hello!”)這句代碼,這句代碼表示什么含義呢?在構造方法中使this關鍵字表示調用類中的構造方法。如果一個類中有多個構造方法,因為其名字都相同,跟類名一致,那么這個this到底是調用哪個構造方法呢?其實,這跟采用其他方法引用構造方法一樣,都是通過形式參數來調用構造方法的。如上例中,this關鍵字后面加上了一個參數,那么就表示其引用的是帶參數的構造方法。如果現在有三個構造方法,分別為不帶參數、帶一個參數、帶兩個參數。那么Java編譯器會根據所傳遞的參數數量的不同,來判斷該調用哪個構造方法。從上面示例中可以看出,this關鍵字不僅可以用來引用成員變量,而且還可以用來引用構造方法。

    不過如果要使用這種方式來調用構造方法的話,有一個語法上的限制。一般來說,利用this關鍵字來調用構造方法,只有在無參數構造方法中第一句使用this調用有參數的構造方法。否則的話,翻譯的時候,就會有錯誤信息。這跟引用成員變量不同。如果引用成員變量的話,this關鍵字是沒有位置上的限制的。如果不熟悉這個限制的話,那么還是老老實實的采用傳統的構造方法調用方式為好。雖然比較麻煩,但是至少不會出錯。

應用三:返回對象的值

    this關鍵字除了可以引用變量或者成員方法之外,還有一個重大的作用就是返回類的引用。如在代碼中,可以使用return this,來返回某個類的引用。此時這個this關鍵字就代表類的名稱。如代碼在上面student類中,那么代碼代表的含義就是return student。可見,這個this關鍵字除了可以引用變量或者成員方法之外,還可以作為類的返回值,這才是this關鍵字最引人注意的地方。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM