技術(shù)大佬:我去,你竟然還不會用 this 關(guān)鍵字

上一篇文章寫的是 Spring Boot 的入門,結(jié)果有讀者留言說,Java 都還沒搞完,搞什么 Spring Boot,唬得我一愣一愣的。那這篇就繼續(xù)來搞 Java,推出廣受好評的我去系列第四集:你竟然還不會用 this 關(guān)鍵字。

“老大,能給說詳細(xì)地說說 this 關(guān)鍵字嗎,總感覺對這個關(guān)鍵字的認(rèn)知不夠全面?!毙⊥跤诌^來找我了,他問的態(tài)度很謙遜,很卑微,但我還是忍不住破口大罵:“我擦,小王,你丫的竟然不會用 this,我當(dāng)初是怎么面試你進(jìn)來的!”

小王被我這句話嚇壞了,趕緊躲到自己崗位上改 bug 去了。我呢,加班加點開始寫這篇文章,真良心用苦啊。在 Java 中,this 關(guān)鍵字指的是當(dāng)前對象(它的方法正在被調(diào)用)的引用,能理解吧,各位親?不理解的話,我們繼續(xù)往下看。

看完再不明白,你過來捶爆我,我保證不還手,只要不打臉。

01、消除字段歧義

我敢賭一毛錢,所有的讀者,不管男女老少,應(yīng)該都知道這種用法,畢竟寫構(gòu)造方法的時候經(jīng)常用啊。誰要不知道,過來,我給你發(fā)一毛錢紅包,只要你臉皮夠厚。

public class Writer {
    private int age;
    private String name;

    public Writer(int age, String name) {
        this.age = age;
        this.name = name;
    }
}

Writer 類有兩個成員變量,分別是 age 和 name,在使用有參構(gòu)造函數(shù)的時候,如果參數(shù)名和成員變量的名字相同,就需要使用 this 關(guān)鍵字消除歧義:this.age 是指成員變量,age 是指構(gòu)造方法的參數(shù)。

02、引用類的其他構(gòu)造方法

當(dāng)一個類的構(gòu)造方法有多個,并且它們之間有交集的話,就可以使用 this 關(guān)鍵字來調(diào)用不同的構(gòu)造方法,從而減少代碼量。

比如說,在無參構(gòu)造方法中調(diào)用有參構(gòu)造方法:

public class Writer {
    private int age;
    private String name;

    public Writer(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public Writer() {
        this(18, "沉默王二");
    }
}

也可以在有參構(gòu)造方法中調(diào)用無參構(gòu)造方法:

public class Writer {
    private int age;
    private String name;

    public Writer(int age, String name) {
        this();
        this.age = age;
        this.name = name;
    }

    public Writer() {
    }
}

需要注意的是,this() 必須是構(gòu)造方法中的第一條語句,否則就會報錯。

03、作為參數(shù)傳遞

在下例中,有一個無參的構(gòu)造方法,里面調(diào)用了 print() 方法,參數(shù)只有一個 this 關(guān)鍵字。

public class ThisTest {
    public ThisTest() {
        print(this);
    }

    private void print(ThisTest thisTest) {
        System.out.println("print " +thisTest);
    }

    public static void main(String[] args) {
        ThisTest test = new ThisTest();
        System.out.println("main " + test);
    }
}

來打印看一下結(jié)果:

print com.cmower.baeldung.this1.ThisTest@573fd745
main com.cmower.baeldung.this1.ThisTest@573fd745

從結(jié)果中可以看得出來,this 就是我們在 main() 方法中使用 new 關(guān)鍵字創(chuàng)建的 ThisTest 對象。

04、鏈?zhǔn)秸{(diào)用

學(xué)過 JavaScript,或者 jQuery 的讀者可能對鏈?zhǔn)秸{(diào)用比較熟悉,類似于 a.b().c().d(),仿佛能無窮無盡調(diào)用下去。

在 Java 中,對應(yīng)的專有名詞叫 Builder 模式,來看一個示例。

public class Writer {
    private int age;
    private String name;
    private String bookName;
    
    public Writer(WriterBuilder builder) {
        this.age = builder.age;
        this.name = builder.name;
        this.bookName = builder.bookName;
    }

    public static class WriterBuilder {
        public String bookName;
        private int age;
        private String name;

        public WriterBuilder(int age, String name) {
            this.age = age;
            this.name = name;
        }

        public WriterBuilder writeBook(String bookName) {
            this.bookName = bookName;
            return this;
        }

        public Writer build() {
            return new Writer(this);
        }
    }
}

Writer 類有三個成員變量,分別是 age、name 和 bookName,還有它們仨對應(yīng)的一個構(gòu)造方法,參數(shù)是一個內(nèi)部靜態(tài)類 WriterBuilder。

內(nèi)部類 WriterBuilder 也有三個成員變量,和 Writer 類一致,不同的是,WriterBuilder 類的構(gòu)造方法里面只有 age 和 name 賦值了,另外一個成員變量 bookName 通過單獨的方法 writeBook() 來賦值,注意,該方法的返回類型是 WriterBuilder,最后使用 return 返回了 this 關(guān)鍵字。

最后的 build() 方法用來創(chuàng)建一個 Writer 對象,參數(shù)為 this 關(guān)鍵字,也就是當(dāng)前的 WriterBuilder 對象。

這時候,創(chuàng)建 Writer 對象就可以通過鏈?zhǔn)秸{(diào)用的方式。

Writer writer = new Writer.WriterBuilder(18,"沉默王二")
                .writeBook("《Web全棧開發(fā)進(jìn)階之路》")
                .build();

05、在內(nèi)部類中訪問外部類對象

說實話,自從 Java 8 的函數(shù)式編程出現(xiàn)后,就很少用到 this 在內(nèi)部類中訪問外部類對象了。來看一個示例:

public class ThisInnerTest {
    private String name;
    
    class InnerClass {
        public InnerClass() {
            ThisInnerTest thisInnerTest = ThisInnerTest.this;
            String outerName = thisInnerTest.name;
        }
    }
}

在內(nèi)部類 InnerClass 的構(gòu)造方法中,通過外部類.this 可以獲取到外部類對象,然后就可以使用外部類的成員變量了,比如說 name。

06、關(guān)于 super

本來想單獨寫一篇 super 關(guān)鍵字的,但可寫的內(nèi)容不多。本質(zhì)上,this 關(guān)鍵字和 super 關(guān)鍵字有蠻多相似之處的,所以,就放在 this 這篇文章的末尾說一說吧。

簡而言之,super 關(guān)鍵字就是用來訪問父類的。

先來看父類:

public class SuperBase {
    String message = "父類";

    public SuperBase(String message) {
        this.message = message;
    }

    public SuperBase() {
    }

    public void printMessage() {
        System.out.println(message);
    }
}

再來看子類:

public class SuperSub extends SuperBase {
    String message = "子類";

    public SuperSub(String message) {
        super(message);
    }

    public SuperSub() {
        super.printMessage();
        printMessage();
    }

    public void getParentMessage() {
        System.out.println(super.message);
    }

    public void printMessage() {
        System.out.println(message);
    }
}

1)super 關(guān)鍵字可用于訪問父類的構(gòu)造方法

你看,子類可以通過 super(message) 來調(diào)用父類的構(gòu)造方法?,F(xiàn)在來新建一個 SuperSub 對象,看看輸出結(jié)果是什么:

SuperSub superSub = new SuperSub("子類的message");

new 關(guān)鍵字在調(diào)用構(gòu)造方法創(chuàng)建子類對象的時候,會通過 super 關(guān)鍵字初始化父類的 message,所以此此時父類的 message 會輸出“子類的message”。

2)super 關(guān)鍵字可以訪問父類的變量

上述例子中的 SuperSub 類中就有,getParentMessage() 通過 super.message 方法父類的同名成員變量 message。

3)當(dāng)方法發(fā)生重寫時,super 關(guān)鍵字可以訪問父類的同名方法

上述例子中的 SuperSub 類中就有,無參的構(gòu)造方法 SuperSub() 中就使用 super.printMessage() 調(diào)用了父類的同名方法。

07、總結(jié)

親愛的讀者朋友,我應(yīng)該說得很全面了吧?我想小王看到了這篇文章后一定會感謝我的良苦用心的,他畢竟是個積極好學(xué)的好同事啊。

如果覺得文章對你有點幫助,請微信搜索「 沉默王二 」第一時間閱讀,回復(fù)「并發(fā)」更有一份阿里大牛重寫的 Java 并發(fā)編程實戰(zhàn),從此再也不用擔(dān)心面試官在這方面的刁難了。

本文已收錄 GitHub,傳送門~ ,里面更有大廠面試完整考點,歡迎 Star。

我是沉默王二,一枚有顏值卻靠才華茍且的程序員。關(guān)注即可提升學(xué)習(xí)效率,別忘了三連啊,點贊、收藏、留言,我不挑,嘻嘻。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容