讀古今文學網 > 編寫高質量代碼:改善Java程序的151個建議 > 建議10:不要在本類中覆蓋靜態導入的變量和方法 >

建議10:不要在本類中覆蓋靜態導入的變量和方法

如果一個類中的方法及屬性與靜態導入的方法及屬性重名會出現什麼問題呢?我們先來看一個正常的靜態導入,代碼如下:


import static java.lang.Math.PI;

import static java.lang.Math.abs;

public class Client{

public static void main(Stringargs){

System.out.println("PI="+PI);

System.out.println("abs(100)="+abs(-100));

}

}


很簡單的例子,打印出靜態常量PI值,計算-100的絕對值。現在的問題是:如果我們在Client類中也定義了PI常量和abs方法,會出現什麼問題?代碼如下:


import static java.lang.Math.PI;

import static java.lang.Math.abs;

public class Client{

//常量名與靜態導入的PI相同

public fnal static String PI="祖沖之";

//方法名與靜態導入的相同

public static int abs(int abs){

return 0;

}

public static void main(Stringargs){

System.out.println("PI="+PI);

System.out.println("abs(100)="+abs(-100));

}

}


以上代碼中,定義了一個PI字符串類型的常量,又定義了一個abs方法,與靜態導入的相同。首先說好消息:編譯器沒有報錯,接下來是不好的消息了:我們不知道哪個屬性和哪個方法被調用了,因為常量名和方法名相同,到底調用了哪一個方法呢?我們運行一下看看結果:


PI=祖沖之

abs(100)=0


很明顯是本地的屬性和方法被引用了,為什麼不是Math類中的屬性和方法呢?那是因為編譯器有一個「最短路徑」原則:如果能夠在本類中查找到的變量、常量、方法,就不會到其他包或父類、接口中查找,以確保本類中的屬性、方法優先。

因此,如果要變更一個被靜態導入的方法,最好的辦法是在原始類中重構,而不是在本類中覆蓋。