1. 程式人生 > >要想學好Java編程,構造器、方法重載、this關鍵字、垃圾回收機制,這4關一定要過!

要想學好Java編程,構造器、方法重載、this關鍵字、垃圾回收機制,這4關一定要過!

社會 tor 沒有 type 遇到 一個 結果 回收 爆笑

有人說,你應該關註時事、財經,甚至流行的電影、電視劇,才有可能趁著熱點寫出爆文;有人說,你別再寫“無聊”的技術文了,因為程序員的圈子真的很小,即便是像鴻洋那樣的招牌大牛,文章是那麽的幹貨,瀏覽量有多少?不到萬吧;有人說,你別妄想在寫作上面知識變現了,因為你寫的文章真的很不優秀,我都不愛看!

我想說,你們說的話我都不愛聽!我也懶得反駁,因為我沒有成功,也就沒有話語權,多說無益。我只想做一名執拗的程序員,靜靜地寫文,哪怕只有一個讀者——有時候,做一件事,並不是想要結果,僅僅只是因為心底那種狂熱的喜歡。

今天,我打算聊聊Java編程中的初始化。

01、使用構造器來確保對象初始化
在Java編程中,無論是對象,還是基本類型,都不允許在未經初始化的情況下使用它們;否則,Java編譯器就會熱情地提醒你——請初始化後再使用。

那,Java是通過什麽機制來確保對象初始化呢?

答案就是“構造器”——類的對象要被正確的初始化,就必須先過構造器這一關。

程序清單1-1:一個帶有構造器的簡單類

class Writer {
public Writer() {
System.out.println("我是一名寫作愛好者");
}

public static void main(String[] args) {
    new Writer();
}

}
當使用關鍵字new來創建一個對象Writer時,就會調用構造器(與類名Writer相同的方法Writer())進行初始化,因此上述程序就會輸出“我是一名寫作愛好者”。

構造方法Writer()沒有參數,因此被稱為無參構造器;事實上,無參構造器是可以省略的——編譯器會自動創建一個無參構造器,被稱為“默認構造器”(Java設計者真的無比明智啊——幫助程序員省去了創建默認構造器的麻煩)。

程序清單1-2:默認構造器

class Writer {
public static void main(String[] args) {
new Writer();
}
}
默認構造器並不會一直“默認”存在,如果已經定義了一個構造器,無論有參還是無參,編譯器將不再自動創建默認構造器。

程序清單1-3:不會一直存在的默認構造器

class Writer {
public Writer(String name) {

System.out.println(name + "是一名寫作愛好者");
}

public static void main(String[] args) {
    new Writer();
    new Writer("沈默王二");
}

}
一旦定義了一個有參構造器,那麽在創建對象的時候就必須傳遞構造器需要的參數,否則編譯器會提示“The constructor Writer() is undefined”(使用new Writer()創建對象對)——這樣做的好處就是,確保對象在初始化的時候符合類設計的初衷(上例中,Writer需要指定作者姓名,所以你在創建Writer對象時不能不傳遞作者姓名)。

02、參差不齊乃幸福本源
讀王小波的《沈默的大多數》,我喜歡上了一句話:“參差不齊乃幸福本源”。王小波的意思可能是想說:一個能容忍不同觀點與不同的生活方式的社會,才是一個幸福的社會。那麽,在Java的世界裏,也有一個幸福的社會。

由於構造器的特殊性(不能與其他成員方法的名字沖突),導致構造器的名字必須和類名保持一致,也就是說,一個類,只能有一個構造器名。這似乎局限了構造器的使用方式。但其實不然,Java允許方法重載——可以只有一個方法名,但方法的參數列表可不盡相同;哎,問題就這麽巧妙的解決了。

程序清單2-1:構造方法的重載

class Writer {
private String name;
private String bookName;

public Writer(String name) {
    this.name = name;
    System.out.println(name + "是一名寫作愛好者");
}

public Writer(String name, String bookName) {
    this.name = name;
    this.bookName = bookName;

    System.out.println(name + "不僅是一名寫作愛好者,還出版了書籍" + bookName);
}

public static void main(String[] args) {
    new Writer("沈默王二");
    new Writer("沈默王三", "《Web全棧開發進階之路》");
}

}
你看,沈默王二沒出版書籍,可以是一名寫作愛好者;沈默王三雖然出版了書籍《Web全棧開發進階之路》,但仍然和王二是好兄弟,並沒有看不起王二(從來沒說過:“王二,你個渣渣,連本書都沒有出版,好意思說自己是寫作愛好者?”)。是不是很和諧?

Java該如何區分重載方法(畢竟參數名相同)呢?上例中,你也看到了,參數個數的不同就可以區分;另外,參數的類型和順序(不建議使用,因為這樣做會讓代碼難以維護,見下例)也可以用來作為區分的條件。

程序清單2-2:難以維護的方法重載(靠順序,別這樣!)

class Writer {
private String name;
private int age;

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

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

}
03、返回當前對象引用的this關鍵字
在很長一段時間裏,我對this關鍵字都避而不見,因為我搞不懂它到底在幹嘛,我所使用它的場合僅限於程序清單2-1(this.name指的是類的成員變量,而name指的是當前方法的參數)。直到我遇見了jQuery(一個快速、簡潔的JavaScript框架)的鏈式調用。

程序清單3-1:jQuery的鏈式調用

$("#canvas").append("我是一塊抹布")
.show();
方法後面還能再緊跟一個方法,就好像一個胯下運球再接一個後仰跳投,超自然超連貫超燃的一連串動作,令人心情感到愉悅。這背後是什麽原理呢?

程序清單3-2:jQuery的鏈式調用的背後

var MyJQ = function(){
}
MyJQ.prototype = {
append : function(content){
console.log("添加內容");
return this;
},
show : function(){
console.log("將元素顯示");
return this;
}
};
var myjq = new MyJQ();
myjq.append("我是一塊抹布").show();
看完程序清單3-2之後,你就會恍然大悟,原來方法的內部返回了一個this,而這個this就是當前對象的引用;也就是說,myjq.append("我是一塊抹布").show();就相當於:myjq.append("我是一塊抹布");myjq.show();。

理解了jQuery的鏈式調用,我們來模擬一下Java當中的鏈式調用(寫作者做完運動後去睡覺)。

程序清單3-3:Java的鏈式調用

class Writer {
public Writer sleep() {
System.out.println("睡一覺");
return this;
}

public Writer ml() {
    System.out.println("做運動");
    return this;
}

public static void main(String[] args) {
    new Writer().ml().sleep();
}

}
04、理想國中的Java垃圾回收
對象要想被正確使用,必須先被初始化,這是一切的開端;那麽,當對象不再被使用後,它就需要被清理掉,要善始善終。假如你遇到一個面試官,他要“強行”問你關於Java垃圾回收的一些問題,你可以提前做好下面這些準備。

Q:為什麽要進行垃圾回收?
A:如果不進行垃圾回收,內存遲早都會被消耗空。除非內存無限大,我們可以任性的分配而不回收,但是事實並非如此。所以,垃圾回收是必須的。

Q:哪些內存需要回收?
A:所謂“要回收的垃圾”無非就是那些不可能再被任何途徑使用的對象。

Q:Java是如何回收垃圾的?
A:深入理解 Java 垃圾回收機制

不過,在我的印象裏,有一副爆笑的動態圖令我印象深刻,它隱喻的是Java的垃圾回收機制。

【寫在最後】

喜歡就推薦分享,因為你的參與讓我在寫作的道路上不再感到孤單。

要想學好Java編程,構造器、方法重載、this關鍵字、垃圾回收機制,這4關一定要過!