如果一个类中的方法及属性与静态导入的方法及属性重名会出现什么问题呢?我们先来看一个正常的静态导入,代码如下:
很简单的例子,打印出静态常量PI值,计算-100的绝对值。现在的问题是:如果我们在Client类中也定义了PI常量和abs方法,会出现什么问题?代码如下:
- import static java.lang.Math.PI;
- import static java.lang.Math.abs;
- public class Client {
- public static void main(String[] args) {
- System.out.println("PI="+PI);
- System.out.println("abs(100)=" +abs(-100));
- }
- }
以上代码中,定义了一个PI字符串类型的常量,又定义了一个abs方法,与静态导入的相同。首先说好消息:编译器没有报错,接下来是不好的消息了:我们不知道哪个属性和哪个方法被调用了,因为常量名和方法名相同,到底调用了哪一个方法呢?我们运行一下看看结果:
- import static java.lang.Math.PI;
- import static java.lang.Math.abs;
- public class Client {
- //常量名与静态导入的PI相同
- public final static String PI="祖冲之";
- //方法名与静态导入的相同
- public static int abs(int abs){
- return 0;
- }
- public static void main(String[] args) {
- System.out.println("PI="+PI);
- System.out.println("abs(100)=" +abs(-100));
- }
- }
- PI=祖冲之
- abs(100)=0
很明显是本地的属性和方法被引用了,为什么不是Math类中的属性和方法呢?那是因为编译器有一个“最短路径”原则:如果能够在本类中查找到的变量、常量、方法,就不会到其他包或父类、接口中查找,以确保本类中的属性、方法优先。
因此,如果要变更一个被静态导入的方法,最好的办法是在原始类中重构,而不是在本类中覆盖。