第五章 初始化與清理(二)

三、this與static 關鍵字

  • this關鍵字

假設一種場景赞辩,現(xiàn)在有一個 類

class A{
   void a(int x){}
}

如果有兩個對象a1雌芽、a2都調用a()方法,那么該方法是如何知道被誰調用辨嗽。
為了能用簡便世落、面向對象的語法來編寫代碼,編譯器為我們做了一些幕后操作糟需,它把所操作對象的引用作為第一個參數傳遞給操作方法屉佳,語句"a1.a(5);"在編譯器的內部表現(xiàn)形式是"a1.a(a1, 5)"。

如果你希望在方法內部獲取對當前對象的引用洲押,Java為我們專門定制了一個關鍵字 this武花。this關鍵字只能在方法內部使用,表示調用方法的那個引用诅诱。如果在方法內部調用類的另一個方法髓堪,則this關鍵字可以省略,編譯器會自動添加。只有當需要明確指出當前對象的引用時干旁,才需要使用this關鍵字驶沼。例如

public class Content  {

    private ArrayList<BrandList> selectedBrandLists;
    private ArrayList<DeviceList> selectedDeviceLists;
    private ArrayList<ComponentList> selectedComponentLists;

    public ArrayList<BrandList> getSelectedBrandLists() {
        return selectedBrandLists;
    }

    public DemandContent setSelectedBrandLists(ArrayList<BrandList> selectedBrandLists) {
        this.selectedBrandLists = selectedBrandLists;
        return this;
    }

    public ArrayList<DeviceList> getSelectedDeviceLists() {
        return selectedDeviceLists;
    }

    public DemandContent setSelectedDeviceLists(ArrayList<DeviceList> selectedDeviceLists) {
        this.selectedDeviceLists = selectedDeviceLists;
        return this;
    }

    public ArrayList<ComponentList> getSelectedComponentLists() {
        return selectedComponentLists;
    }

    public DemandContent setSelectedComponentLists(ArrayList<ComponentList> selectedComponentLists) {
        this.selectedComponentLists = selectedComponentLists;
        return this;
    }
}

我們使set方法返回當前類對象引用的目的是為了在設置對象內容的時候可以連續(xù)調用set方法

Content content = new Content();
content.setSelectedBrandLists(selectedBrandLists)
                .setSelectedDeviceLists(selectedDeviceLists)
                .setSelectedComponentLists(selectedComponentLists);

相比于

Content content = new Content();
content.setSelectedBrandLists(selectedBrandLists)
content.setSelectedDeviceLists(selectedDeviceLists)
content.setSelectedComponentLists(selectedComponentLists);

省去了一些不必要的步驟。這種方式在Builder模式中比較常見争群。

當一個類有多個構造器回怜,有時為了避免重復編寫代碼,可以希望在一個構造器內調用另一個構造器换薄,可以用this關鍵字做到這一點玉雾。
在構造器中,如果為this添加參數列表轻要,那么將會是對某個符合參數列表的構造器的直接調用复旬。這樣,調用其他構造器就有了直接的途徑冲泥。

private Context mContext;
private OnLoginDataCheckerListener onLoginDataCheckerListener;
private ILoginModel iLoginModel;

 public LoginPresenter(Context mContext, OnLoginDataCheckerListener onLoginDataCheckerListener,
                          OnGetVCodeListener onGetVCodeListener) {
        this(mContext, onLoginDataCheckerListener);    //調用其他構造器
        this.onGetVCodeListener = onGetVCodeListener;  //避免與參數的同名歧義驹碍,使用this.onGetVCodeListener代表數據成員
}

private LoginPresenter(Context mContext, OnLoginDataCheckerListener onLoginDataCheckerListener) {
        this.mContext = mContext;
        this.onLoginDataCheckerListener = onLoginDataCheckerListener;
        this.iLoginModel = new LoginModel();
}

值得注意的是,只能使用this調用一個其他構造器凡恍,并且必須將調用語句置于最起始處志秃,否則編譯無法通過

this關鍵字的作用也不僅限于此,有機會再專門寫一篇記總結一下嚼酝。

  • static關鍵字

static方法就是沒有this的方法浮还。在static方法內部不能調用非靜態(tài)方法,反過來是可以的闽巩。而且可以在沒有創(chuàng)建任何對象的前提下钧舌,僅僅通過類本身來調用static方法。這實際上正是static方法的主要用途又官。

1. static方法
static方法一般稱作靜態(tài)方法延刘,由于靜態(tài)方法不依賴于任何對象就可以進行訪問,因此對于靜態(tài)方法來說六敬,是沒有this的,因為它不依附于任何對象驾荣,既然都沒有對象外构,就談不上this了。并且由于這個特性播掷,在靜態(tài)方法中不能訪問類的非靜態(tài)成員變量和非靜態(tài)成員方法审编,因為非靜態(tài)成員方法/變量都是必須依賴具體的對象才能夠被調用。

但是要注意的是歧匈,雖然在靜態(tài)方法中不能訪問非靜態(tài)成員方法和非靜態(tài)成員變量垒酬,但是在非靜態(tài)成員方法中是可以訪問靜態(tài)成員方法/變量的。

另外記住,關于構造器是否是static方法可參考:http://blog.csdn.net/qq_17864929/article/details/48006835
2. static變量

static變量也稱作靜態(tài)變量勘究,靜態(tài)變量和非靜態(tài)變量的區(qū)別是:靜態(tài)變量被所有的對象所共享矮湘,在內存中只有一個副本,它當且僅當在類初次加載時會被初始化口糕。而非靜態(tài)變量是對象所擁有的缅阳,在創(chuàng)建對象的時候被初始化,存在多個副本景描,各個對象擁有的副本互不影響十办。

static成員變量的初始化順序按照定義的順序進行初始化。

3. static代碼塊

static關鍵字還有一個比較關鍵的作用就是 用來形成靜態(tài)代碼塊以優(yōu)化程序性能超棺。static塊可以置于類中的任何地方向族,類中可以有多個static塊。在類初次被加載的時候棠绘,會按照static塊的順序來執(zhí)行每個static塊炸枣,并且只會執(zhí)行一次。

為什么說static塊可以用來優(yōu)化程序性能弄唧,是因為它的特性:只會在類加載的時候執(zhí)行一次适肠。舉個栗子

class Person{
    private Date birthDate;
     
    public Person(Date birthDate) {
        this.birthDate = birthDate;
    }
     
    boolean isBornBoomer() {
        Date startDate = Date.valueOf("1946");
        Date endDate = Date.valueOf("1964");
        return birthDate.compareTo(startDate)>=0 && birthDate.compareTo(endDate) < 0;
    }
}

isBornBoomer是用來這個人是否是1946-1964年出生的,而每次isBornBoomer被調用的時候候引,都會生成startDate和birthDate兩個對象侯养,造成了空間浪費,如果改成這樣效率會更好:

class Person{
    private Date birthDate;
    private static Date startDate,endDate;
    static{
        startDate = Date.valueOf("1946");
        endDate = Date.valueOf("1964");
    }
     
    public Person(Date birthDate) {
        this.birthDate = birthDate;
    }
     
    boolean isBornBoomer() {
        return birthDate.compareTo(startDate)>=0 && birthDate.compareTo(endDate) < 0;
    }
}

因此澄干,很多時候會將一些只需要進行一次的初始化操作都放在static代碼塊中進行逛揩。
4. static關鍵字的一些誤區(qū)
(1)static關鍵字會改變類中成員的訪問權限嗎?
  有些初學的朋友會將java中的static與C/C++中的static關鍵字的功能混淆了麸俘。在這里只需要記住一點:與C/C++中的static不同辩稽,Java中的static關鍵字不會影響到變量或者方法的作用域。在Java中能夠影響到訪問權限的只有private从媚、public逞泄、protected(包括包訪問權限)這幾個關鍵字“菪В看下面的例子就明白了:

example

提示錯誤"Person.age 不可視"喷众,這說明static關鍵字并不會改變變量和方法的訪問權限。

(2)能通過this訪問靜態(tài)成員變量嗎紧憾?
  雖然對于靜態(tài)方法來說沒有this到千,那么在非靜態(tài)方法中能夠通過this訪問靜態(tài)成員變量嗎?先看下面的一個例子赴穗,這段代碼輸出的結果是什么憔四?

public class Main {  
    static int value = 33;
 
    public static void main(String[] args) throws Exception{
        new Main().printValue();
    }
 
    private void printValue(){
        int value = 3;
        System.out.println(this.value);    //輸出33
    }
}

這里面主要考察隊this和static的理解膀息。this代表什么?this代表當前對象了赵,那么通過new Main()來調用printValue的話潜支,當前對象就是通過new Main()生成的對象。而static變量是被對象所享有的斟览,因此在printValue中的this.value的值毫無疑問是33毁腿。在printValue方法內部的value是局部變量,根本不可能與this關聯(lián)苛茂,所以輸出結果是33已烤。在這里永遠要記住一點:靜態(tài)成員變量雖然獨立于對象,但是不代表不可以通過對象去訪問妓羊,所有的靜態(tài)方法和靜態(tài)變量都可以通過對象訪問(只要訪問權限足夠)胯究。

(3)static能作用于局部變量么?
  在C/C++中static是可以作用域局部變量的躁绸,但是在Java中切記:static是不允許用來修飾局部變量裕循。不要問為什么,這是Java語法的規(guī)定净刮。

具體原因可以參考這篇博文的討論:http://www.debugease.com/j2se/178932.html


參考

《Java編程思想》
https://www.cnblogs.com/dolphin0520/p/3799052.html
http://www.debugease.com/j2se/178932.html
http://blog.csdn.net/qq_17864929/article/details/48006835

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末剥哑,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子淹父,更是在濱河造成了極大的恐慌株婴,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,039評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件暑认,死亡現(xiàn)場離奇詭異困介,居然都是意外死亡,警方通過查閱死者的電腦和手機蘸际,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評論 3 395
  • 文/潘曉璐 我一進店門座哩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人粮彤,你說我怎么就攤上這事根穷。” “怎么了驾诈?”我有些...
    開封第一講書人閱讀 165,417評論 0 356
  • 文/不壞的土叔 我叫張陵缠诅,是天一觀的道長。 經常有香客問我乍迄,道長,這世上最難降的妖魔是什么士败? 我笑而不...
    開封第一講書人閱讀 58,868評論 1 295
  • 正文 為了忘掉前任闯两,我火速辦了婚禮褥伴,結果婚禮上,老公的妹妹穿的比我還像新娘漾狼。我一直安慰自己重慢,他們只是感情好,可當我...
    茶點故事閱讀 67,892評論 6 392
  • 文/花漫 我一把揭開白布逊躁。 她就那樣靜靜地躺著似踱,像睡著了一般。 火紅的嫁衣襯著肌膚如雪稽煤。 梳的紋絲不亂的頭發(fā)上核芽,一...
    開封第一講書人閱讀 51,692評論 1 305
  • 那天,我揣著相機與錄音酵熙,去河邊找鬼轧简。 笑死,一個胖子當著我的面吹牛匾二,可吹牛的內容都是我干的哮独。 我是一名探鬼主播,決...
    沈念sama閱讀 40,416評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼察藐,長吁一口氣:“原來是場噩夢啊……” “哼皮璧!你這毒婦竟也來了?” 一聲冷哼從身側響起分飞,我...
    開封第一講書人閱讀 39,326評論 0 276
  • 序言:老撾萬榮一對情侶失蹤悴务,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后浸须,有當地人在樹林里發(fā)現(xiàn)了一具尸體惨寿,經...
    沈念sama閱讀 45,782評論 1 316
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,957評論 3 337
  • 正文 我和宋清朗相戀三年删窒,在試婚紗的時候發(fā)現(xiàn)自己被綠了裂垦。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,102評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡肌索,死狀恐怖蕉拢,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情诚亚,我是刑警寧澤晕换,帶...
    沈念sama閱讀 35,790評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站站宗,受9級特大地震影響闸准,放射性物質發(fā)生泄漏。R本人自食惡果不足惜梢灭,卻給世界環(huán)境...
    茶點故事閱讀 41,442評論 3 331
  • 文/蒙蒙 一夷家、第九天 我趴在偏房一處隱蔽的房頂上張望蒸其。 院中可真熱鬧,春花似錦库快、人聲如沸摸袁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽靠汁。三九已至,卻和暖如春闽铐,著一層夾襖步出監(jiān)牢的瞬間蝶怔,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評論 1 272
  • 我被黑心中介騙來泰國打工阳啥, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留添谊,地道東北人。 一個月前我還...
    沈念sama閱讀 48,332評論 3 373
  • 正文 我出身青樓察迟,卻偏偏與公主長得像斩狱,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子扎瓶,可洞房花燭夜當晚...
    茶點故事閱讀 45,044評論 2 355

推薦閱讀更多精彩內容

  • 1. Java基礎部分 基礎部分的順序:基本語法所踊,類相關的語法,內部類的語法概荷,繼承相關的語法秕岛,異常的語法,線程的語...
    子非魚_t_閱讀 31,639評論 18 399
  • 已經很久沒有遇到一個活成搞笑符號的人了误证。孫鋼老師继薛,教練江湖人稱“質疑哥”,絕對算一個愈捅。 現(xiàn)在的癥狀是遏考,只要見到質疑...
    WonderLiwen閱讀 767評論 0 3
  • 沒有一點過年的感覺,俗話說過了臘八就是年蓝谨,過了臘月二十八也還是沒有年的感覺灌具,家人忙忙碌碌買新衣,置辦年貨譬巫,收...
    何處為初閱讀 155評論 0 0
  • 春節(jié)檔最火的電影之一咖楣,《唐探2》。 春節(jié)檔老面孔之一芦昔,王寶強诱贿。 Sir去看了,也熟悉咕缎,也陌生瘪松。 之前的印象咸作,還停留...
    Sir電影閱讀 2,143評論 7 54