建議9:少用靜態(tài)導(dǎo)入
從Java 5開始引入了靜態(tài)導(dǎo)入語法(import static)墓猎,其目是為了減少字符輸入量卷胯,提高代碼的可閱讀性,以便更好地理解程序辜贵。我們先來看一個不使用靜態(tài)導(dǎo)入的例子丘喻,也就是一般導(dǎo)入:
public class MathUtils{
//計算圓面積
public static double calCircleArea(double r){
return Math.PI * r * r;
}
//計算球面積
public static double calBallArea(double r){
return 4* Math.PI * r * r;
}
}
這是很簡單的數(shù)學(xué)工具類,我們在這兩個計算面積的方法中都引入了java.lang.Math類(該類是默認導(dǎo)入的)中的PI(圓周率)常量念颈,而Math這個類寫在這里有點多余,特別是如果MathUtils中的方法比較多時连霉,如果每次都要敲入Math這個類榴芳,繁瑣且多余,靜態(tài)導(dǎo)入可解決此類問題跺撼,使用靜態(tài)導(dǎo)入后的程序如下:
import static java.lang.Math.PI;
public class MathUtils{
//計算圓面積
public static double calCircleArea(double r){
return PI * r * r;
}
//計算球面積
public static double calBallArea(double r){
return 4 * PI * r * r;
}
}
靜態(tài)導(dǎo)入的作用是把Math類中的PI常量引入到本類中窟感,這會使程序更簡單,更容易閱讀歉井,只要看到PI就知道這是圓周率柿祈,不用每次都要把類名寫全了。但是哩至,濫用靜態(tài)導(dǎo)入會使程序更難閱讀躏嚎,更難維護。靜態(tài)導(dǎo)入后菩貌,代碼中就不用再寫類名了卢佣,但是我們知道類是“一類事物的描述”,缺少了類名的修飾箭阶,靜態(tài)屬性和靜態(tài)方法的表象意義可以被無限放大虚茶,這會讓閱讀者很難弄清楚其屬性或方法代表何意,甚至是哪一個類的屬性(方法)都要思考一番(當然仇参,IDE友好提示功能是另說)嘹叫,特別是在一個類中有多個靜態(tài)導(dǎo)入語句時,若還使用了*(星號)通配符诈乒,把一個類的所有靜態(tài)元素都導(dǎo)入進來了罩扇,那簡直就是惡夢。我們來看一段例子:
import static java.lang.Double.*;
import static java.lang.Math.*;
import static java.lang.Integer.*;
import static java.text.NumberFormat.*;
public class Client {
//輸入半徑和精度要求抓谴,計算面積
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類的一個轉(zhuǎn)換方法,這看名稱也能猜測到滩届。那緊接著的getInstance方法是哪個類的集侯?是Client本地類被啼?不對呀,沒有這個方法棠枉,哦浓体,原來是NumberFormate類的方法,這和formateMessage本地方法沒有任何區(qū)別了—這代碼也太難閱讀了辈讶,非機器不可閱讀命浴。
所以,對于靜態(tài)導(dǎo)入贱除,一定要遵循兩個規(guī)則:
- 不使用*(星號)通配符生闲,除非是導(dǎo)入靜態(tà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方法是用來斷言兩個值是否相等的,assertFalse方法則是斷言表達式為假录语,如此確實減少了代碼量倍啥,而且代碼的可讀性也提高了,這也是靜態(tài)導(dǎo)入用到正確地方所帶來的好處