我沒(méi)按照順序讀書(shū)的,看什么感興趣就先讀什么,呵呵。
public class Confusing {
private Confusing(Object o) {
System.out.println("Object");
}
private Confusing(double[] dArray) {
System.out.println("double array");
}
public static void main(String[] args) {
new Confusing(null);
}
}
你可能認為應該隨機調用這兩個(gè)重載函數中的某一個(gè),不幸的是你會(huì )發(fā)現一直重復輸出的是:doublearray。證明只有第二個(gè)函數被調用。為何?這跟java對重載函數的解析有關(guān),JAVA對重載函數的解析分為兩步,首先查找出所有可獲得的并且可應用的構造器或者方法,第2步從這些方法中尋找出適合“最精確”的。在本例中,第1個(gè)函數能接受的參數范圍大于第二個(gè)函數,所以對于null來(lái)說(shuō),第二個(gè)函數更為“精確”。這就告訴我們一點(diǎn),在撰寫(xiě)重載函數時(shí),請確保所有重載版本所接受的參數類(lèi)型盡量做到不兼容!
2。Null與Void,很有趣的例子:
public class Null {
public static void greet() {
System.out.println("Hello world!");
}
public static void main(String[] args) {
((Null) null).greet();
}
}
這個(gè)能編譯通過(guò)嗎?你可能要問(wèn),呵呵,確實(shí)可以,打印經(jīng)典的HelloWorld。本質(zhì)上,((Null)null).greet();等價(jià)于Null.greet();,因為greet是staticmethod,即類(lèi)方法,它與具體的對象實(shí)例無(wú)關(guān)!雖然你在此指定了表達式null,但此值將被忽略。這樣的寫(xiě)法容易造成混淆,在調用類(lèi)方法(靜態(tài)方法時(shí))請盡量使用類(lèi)名來(lái)調用!
3。此章中有幾個(gè)例子詳細討論了類(lèi)中的變量初始化順序問(wèn)題。需要避免幾個(gè)種情況:
A。要當心類(lèi)的初始化順序,特別是在你無(wú)法確定的情況下,請編寫(xiě)適當的測試。
B。不要在構造函數中調用可能被覆寫(xiě)的方法。因為這些方法可能在子類(lèi)中被覆寫(xiě),導致不可預知的行為。
C。對靜態(tài)變量的初始化需要特別注意順序,靜態(tài)域,甚至是final型的靜態(tài)域,都可能在它們被正確地初始化之前被使用。
4??纯匆粋€(gè)程序,動(dòng)態(tài)綁定與靜態(tài)綁定。
class Dog {
public static void bark() {
System.out.print("woof ");
}
}
class Basenji extends Dog {
public static void bark() { }
}
public class Bark {
public static void main(String args[]) {
Dog woofer = new Dog();
Dog nipper = new Basenji();
woofer.bark();
nipper.bark();
}
}
啊,你可能一開(kāi)始就認為這應該是動(dòng)態(tài)綁定吧,多態(tài)性??!那么應該只打印一個(gè)woof吧!可并非如此,可憐的小狗Basenji也叫喚了(據書(shū)中所說(shuō),此種狗在非洲,而且從來(lái)不叫喚,無(wú)法想象這世上有不叫喚的狗,呵呵)。問(wèn)題就在于bark是一個(gè)靜態(tài)方法,而靜態(tài)方法的調用不存在任何動(dòng)態(tài)綁定機制!對于靜態(tài)方法,只會(huì )根據調用者的編譯期類(lèi)型進(jìn)行調用,woofer,nipper都被聲明為Dog,他們的編譯期類(lèi)型相同。你可能要問(wèn),子類(lèi)Basenji中的bark()方法不是覆寫(xiě)了父類(lèi)中的bark方法,那么是怎么回事?答案是它隱藏了父類(lèi)中的bark方法,靜態(tài)方法是不能被覆寫(xiě)的,他們只能被隱藏。要想使這只可憐的小狗回歸不叫喚的“正常”狀態(tài),去掉方法之前的static標簽即可。
5。instanceof操作符的特點(diǎn):
A。null instanceof String時(shí)返回false,即左操作數為null時(shí)返回false
B。instantceof在編譯期就會(huì )判斷左操作數是否是右操作數的子類(lèi)型,如果不是,在編譯期就無(wú)法通過(guò)
C。編譯期通過(guò)了,不意味著(zhù)左操作數就是右操作數的類(lèi)型或者子類(lèi)型了,當你進(jìn)行轉型操作時(shí)將進(jìn)行運行期判斷,如轉型失敗拋出ClassCastException。
6。我們經(jīng)常遇到這樣的需求,跟蹤一個(gè)類(lèi)創(chuàng )建出來(lái)的實(shí)例個(gè)數,典型方法是在它的構造函數中遞增一個(gè)私有的靜態(tài)變量,如:
public class Creator {
public static void main(String[] args) {
for (int i = 0; i < 100; i++)
Creature creature = new Creature();
System.out.println(Creature.numCreated());
}
}
class Creature {
private static long numCreated = 0;
public Creature() {
numCreated++;
}
public static long numCreated() {
return numCreated;
}
}
你嘗試著(zhù)運行此程序,并指望它打印100,可惜,它沒(méi)有,因為你連編譯都沒(méi)辦法通過(guò)。。。。。為什么?出錯信息如下:
E:\book\Java\Javapuzzlers\src\com\denny_blue\puzzlers\classy\Creator.java:18: 不是語(yǔ)句
Creature creature = new Creature();
E:\book\Java\Javapuzzlers\src\com\denny_blue\puzzlers\classy\Creator.java:18: 需要 ‘;‘
Creature creature = new Creature();
2 錯誤
很奇怪是不?其實(shí)很簡(jiǎn)單, Creature creature = new Creature();這是一句local variabledeclarationstatement,而java語(yǔ)言規范(JLS14.4)是不允許一個(gè)本地變量聲明語(yǔ)句作為一條語(yǔ)句在for,while或者do中循環(huán)執行的,它只能直接出現在一個(gè)語(yǔ)句塊中(block),所以簡(jiǎn)單的解決辦法就是給這句話(huà)加上{},或者
for (int i = 0; i < 100; i++)
new Creature();
編譯通過(guò),?,F在也可以正常打印出100了,還有個(gè)問(wèn)題,如果有多線(xiàn)程并行地創(chuàng )建對象,那么我們需要同步計數器代碼和訪(fǎng)問(wèn)計數器的代碼:
class Creature {
private static long numCreated = 0;
public Creature() {
synchronized (Creature.class){
numCreated++;
}
}
public static synchronized long numCreated() {
return numCreated;
}
}
如果你使用JDK5或者更新的版本,你可以使用新引入的ActiomicLong,這實(shí)在是好東西,我對JDK5新引入的這個(gè)并發(fā)包了解太少。它在面臨并發(fā)時(shí)可以繞過(guò)同步需求:
import java.util.concurrent.atomic.AtomicLong;
/**
*
* @author dennis
*/
public class Creature {
private static AtomicLong numCreated=new AtomicLong();
/** Creates a new instance of Creature */
public Creature() {
numCreated.incrementAndGet();
}
public static long numCreated(){
return numCreated;
}
}
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=708983
聯(lián)系客服