從Java 5 開始引入了靜態導入語法(import static),其目是爲了減小字符輸入量,提升代碼的可閱讀性,以便更好地理解程序。咱們先來看一個不使用靜態導入的例子,也就是通常導入:
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;
}
}
這是很簡單的數學工具類,咱們在這兩個計算面積的方法中都引入了java.lang.Math 類(該類是默認導入的)中的PI(圓周率)常量,而Math 這個類寫在這裏有點多餘,特別是若是MathUtils 中的方法比較多時,若是每次都要敲入Math 這個類,繁瑣且多餘,靜態導入可解決此類問題,使用靜態導入後的程序以下:
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;
}
}
靜態導入的做用是把Math 類中的PI 常量引入到本類中,這會使程序更簡單,更容易閱讀,只要看到PI 就知道這是圓周率,不用每次都要把類名寫全了。可是,濫用靜態導入會使程序更難閱讀,更難維護。靜態導入後,代碼中就不用再寫類名了,可是咱們知道類是 「一類事物的描述」,缺乏了類名的修飾,靜態屬性和靜態方法的表象意義能夠被無限放大,這會讓閱讀者很難弄清楚其屬性或方法表明何意,甚至是哪個類的屬 性(方法)都要思考一番(固然,IDE 友好提示功能是另說),特別是在一個類中有多個靜態導入語句時,若還使用了*(星號)通配符,把一個類的全部靜態元素都導入進來了,那簡直就是惡夢。咱們 來看一段例子:
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 類的一個轉換方法,這看名稱也能猜想到。那緊接着的getInstance 方法是哪一個類的?是Client 本地類?不對呀,沒有這個方法,哦,原來是NumberFormate 類的方法,這和formateMessage 本地方法沒有任何區別了—這代碼也太難閱讀了,非機器不可閱讀。因此,對於靜態導入,必定要遵循兩個規則:java
何爲具備明確、清晰表象意義的工具類?咱們來看看JUnit 4 中使用的靜態導入的例子,代碼以下:
import static org.junit.Assert.*;
public class DaoTest {
@Test
public void testInsert(){
// 斷言
assertEquals("foo", "foo");
assertFalse(Boolean.FALSE);
}
}
咱們從程序中很容易判斷出assertEquals 方法是用來斷言兩個值是否相等的,assertFalse方法則是斷言表達式爲假,如此確實減小了代碼量,並且代碼的可讀性也提升了,這也是靜態導入用到正確地方所帶來的好處。git