Java提供了静态导入特性,静态导入扩展了import关键字的功能。通过在import后面添加static关键字,可以使用import语句导入类或接口的静态成员。当使用静态导入时,可以直接通过名称引用静态成员,而不必使用它们的类名进行限定,从而简化并缩短使用静态成员所需的方法。
为了理解静态导入的方法,看一个不使用静态导入的例子。下面的程序计算直角三角形的斜边。程序使用Java内置数学类Math的两个静态方法,Math类是java.lang包一部分。第一个方法是Math.pow(),该方法返回指定幂的幂值。第二个方法是Math.sqrt(),该方法返回参数的平方根。
//Compute the hypotenuse of a right triangle.
public class Hypot {
public static void main(String[] args) {
double side1,side2;
double hypot;
side1=3.0;
side2=4.0;
//Notice how sqrt() and pow() must be qualified by
//their class name,which is Math.
hypot = Math.sqrt(Math.pow(side1,2)+Math.pow(side2,2));
System.out.println("Given sides of lengths "+side1+" and "+side2+" the hypotenuse is "+hypot);
}
}
因为pow()和sqrt()是静态方法,所以必须通过类名Math调用它们。这使得斜边的计算有些笨拙:
hypot = Math.sqrt(Math.pow(side1,2)+Math.pow(side2,2));
正如这个例子演示的,每次使用pow()或sqrt()(以及所有其他数学方法,如sin()、cos()、tan())方法时,都必须指定类名会变得单调乏味。
通过静态导入可以消除这些单调乏味的指定类名的操作,如前面程序的下面这个版本所示:
//Use static import to bring sqrt() and pow() into view.
import static java.lang.Math.sqrt;
import static java.lang.Math.pow;
//Compute the hypotenuse of a right triangle.
public class Hypot {
public static void main(String[] args) {
double side1,side2;
double hypot;
side1=3.0;
side2=4.0;
//Here,sqrt() and pow() can be called by themselves.
//their class name,which is Math.
hypot = Math.sqrt(pow(side1,2)+pow(side2,2));
System.out.println("Given sides of lengths "+side1+" and "+side2+" the hypotenuse is "+hypot);
}
}
在这个版本中,名称sqrt和pow通过它们的静态导入语句变得可以直接使用:
import static java.lang.Math.sqrt;
import static java.lang.Math.pow;
在这些语句之后,不再需要使用类名限定sqrt()和pow()。所以,可以更方便地指定斜边的计算,如下所示:
hypot = Math.sqrt(pow(side1,2)+pow(side2,2));
可以看出,这种形式更加容易阅读
静态导入语句有两种形式。第一种形式引入单个名称,前面程序使用的就是这种形式,如下所示:
import static pkg.type-name.static-member-name;
其中,type-name是包含所需静态成员的类或接口的名称,pkg指定完成包名,成员名称是由static-mamber-name指定的。
静态导入语句的第二种形式是导入给定类或接口的所有静态成员,如下所示:
import static pkg.type-name.*;
如果要使用在某个类中定义的多个静态方法或域变量,那么使用这种形式不必逐个指定就可以导入它们,所以,前面的程序可以使用一条import语句导入pow()和sqrt()成员(以及Math类的所有静态成员):
import static java.lang.Math.*;
当然,静态导入不仅仅局限于Math类,也不仅仅局限于方法。例如,下面这条语句导入了静态的System.out:
import static java.lang.System.out;
有了这条语句之后,向控制台输出时就可以不再使用System限定out,如下所示:
out.println("After importing System.out,you can use out directly.");
向刚才显示的那样导入System.out是否是一个好主意,还应当视具体情况而定。尽管可以缩短语句,但是对于阅读程序的所有人来说,将无法立即弄清楚out引用的是system.out。
另外一点,除了导入Java API定义的接口和类的静态成员外,也可以使用静态导入语句导入我们自己创建的接口和类的静态成员。
尽管静态导入很方便,但是注意不要滥用。记住,Java将类库组织到包中的目的是避免名称空间发生冲突。当导入静态成员时,就将这些成员带入全局名称空间。因此,这会增加潜在的名称空间冲突以及无意中隐藏其他名称的风险。如果在程序中只使用静态成员一两次,最好不要导入它们。此外,有些静态成员,例如System.out,很容易识别,您可能不希望导入它们。静态导入时针对重复使用某个静态成员这类情况设计的。例如执行一系列数学计算。总之,应当使用但不要滥用这一特性。