建議9:少用靜態(tài)導(dǎo)入
從Java 5開始引入了靜態(tài)導(dǎo)入語(yǔ)法(import static),其目是為了減少字符輸入量,提高代碼的可閱讀性,以便更好地理解程序。我們先來(lái)看一個(gè)不使用靜態(tài)導(dǎo)入的例子,也就是一般導(dǎo)入:
public class MathUtils{
//計(jì)算圓面積
public static double calCircleArea(double r){
return Math.PI * r * r;
}
//計(jì)算球面積
public static double calBallArea(double r){
return 4* Math.PI * r * r;
}
}
這是很簡(jiǎn)單的數(shù)學(xué)工具類,我們?cè)谶@兩個(gè)計(jì)算面積的方法中都引入了java.lang.Math類(該類是默認(rèn)導(dǎo)入的)中的PI(圓周率)常量,而Math這個(gè)類寫在這里有點(diǎn)多余,特別是如果MathUtils中的方法比較多時(shí),如果每次都要敲入Math這個(gè)類,繁瑣且多余,靜態(tài)導(dǎo)入可解決此類問(wèn)題,使用靜態(tài)導(dǎo)入后的程序如下:
import static java.lang.Math.PI;
public class MathUtils{
//計(jì)算圓面積
public static double calCircleArea(double r){
return PI * r * r;
}
//計(jì)算球面積
public static double calBallArea(double r){
return 4 * PI * r * r;
}
}
靜態(tài)導(dǎo)入的作用是把Math類中的PI常量引入到本類中,這會(huì)使程序更簡(jiǎn)單,更容易閱讀,只要看到PI就知道這是圓周率,不用每次都要把類名寫全了。但是,濫用靜態(tài)導(dǎo)入會(huì)使程序更難閱讀,更難維護(hù)。靜態(tài)導(dǎo)入后,代碼中就不用再寫類名了,但是我們知道類是“一類事物的描述”,缺少了類名的修飾,靜態(tài)屬性和靜態(tài)方法的表象意義可以被無(wú)限放大,這會(huì)讓閱讀者很難弄清楚其屬性或方法代表何意,甚至是哪一個(gè)類的屬性(方法)都要思考一番(當(dāng)然,IDE友好提示功能是另說(shuō)),特別是在一個(gè)類中有多個(gè)靜態(tài)導(dǎo)入語(yǔ)句時(shí),若還使用了*(星號(hào))通配符,把一個(gè)類的所有靜態(tài)元素都導(dǎo)入進(jìn)來(lái)了,那簡(jiǎn)直就是惡夢(mèng)。我們來(lái)看一段例子:
import static java.lang.Double.*;
import static java.lang.Math.*;
import static java.lang.Integer.*;
import static java.text.NumberFormat.*;
public class Client {
//輸入半徑和精度要求,計(jì)算面積
public static void main(String[] args) {
double s = PI * parseDouble(args[0]);
NumberFormat nf = getInstance();
nf.setMaximumFractionDigits(parseInt(args[1]));
formatMessage(nf.format(s));
}
//格式化消息輸出
public static void formatMessage(String s){
System.out.println("圓面積是:"+s);
}
}
就這么一段程序,看著就讓人火大:常量PI,這知道,是圓周率;parseDouble方法可能是Double類的一個(gè)轉(zhuǎn)換方法,這看名稱也能猜測(cè)到。那緊接著的getInstance方法是哪個(gè)類的?是Client本地類?不對(duì)呀,沒有這個(gè)方法,哦,原來(lái)是NumberFormate類的方法,這和formateMessage本地方法沒有任何區(qū)別了—這代碼也太難閱讀了,非機(jī)器不可閱讀。
所以,對(duì)于靜態(tài)導(dǎo)入,一定要遵循兩個(gè)規(guī)則:
- 不使用*(星號(hào))通配符,除非是導(dǎo)入靜態(tài)常量類(只包含常量的類或接口)。
- 方法名是具有明確、清晰表象意義的工具類。
何為具有明確、清晰表象意義的工具類?我們來(lái)看看JUnit 4中使用的靜態(tài)導(dǎo)入的例子,代碼如下:
import static org.junit.Assert.*;
public class DaoTest {
@Test
public void testInsert(){
//斷言
assertEquals("foo", "foo");
assertFalse(Boolean.FALSE);
}
}
我們從程序中很容易判斷出assertEquals方法是用來(lái)斷言兩個(gè)值是否相等的,assertFalse方法則是斷言表達(dá)式為假,如此確實(shí)減少了代碼量,而且代碼的可讀性也提高了,這也是靜態(tài)導(dǎo)入用到正確地方所帶來(lái)的好處