静态方法调用

use*_*459 16 java syntax static

我们可以在不提及Java中的类名的情况下调用静态方法吗?

Bri*_*new 35

是的你可以.检查静态导入.您必须在import语句中提及类名,但之后您不必使用链接文章中的.eg:

import static java.lang.Math.abs;
import static java.lang.Math.max;

int xDist = abs(destination.getX() - x);
int yDist = abs(destination.getY() - y);
return max(xDist, yDist);
Run Code Online (Sandbox Code Playgroud)

在Java 5中引入.


pol*_*nts 20

是的,您可以在static不提及类名的情况下调用方法.有import static(确切的机制参见JLS 7.5.4),但即使没有它,如果名称可以解析(参见JLS 15.12.1的确切机制)而没有完全限定类,它将起作用.

以下代码"Hello world!"按预期编译和打印.

import static java.lang.System.out;

public class Test {
   static String greeting() {
      return "Hello world!";
   }
   public static void main(String[] args) {
      out.println(greeting());
   }
}
Run Code Online (Sandbox Code Playgroud)

outprintln语句中实际上是static类的字段访问java.lang.System,而不是static方法,但它static仍然是成员访问.greeting()是一个static方法调用,可以省略类名,因为可以在不完全限定名称的情况下解析其引用.


现在让我们问一下这是不是一个好主意.除非你static从同一个类中调用一个方法,否则一般都不要忽略类名!

让我们static import先关注一下.该指南引用:

那么什么时候应该使用静态导入?非常谨慎!只有在您试图声明常量的本地副本或滥用继承(Constant Interface Antipattern)时才使用它.换句话说,当您需要频繁访问来自一个或两个类的静态成员时,请使用它.如果过度使用静态导入功能,它可能会使您的程序无法读取且无法维护,使用static您导入的所有成员污染其命名空间.您的代码的读者(包括您,在您编写它几个月后)将不知道静态成员来自哪个类.从类中导入所有静态成员对可读性特别有害; 如果您只需要一个或两个成员,请单独导入它们.如果使用得当,静态导入可以通过删除重复类名的样板来使程序更具可读性.

通过以下示例使案例变得更加强大:

class Base {
    void task1() {
        System.out.println("Base.task1");
    }
    static void task2() {
        System.out.println("Base.task2");
    }
}

class Child extends Base {
    void task1() {
        System.out.println("Child.task1");          
    }
    static void task2() {
        System.out.println("Child.task2");
    }       
}

//....
Base sweetChildOMine = new Child();
sweetChildOMine.task1(); // prints "Child.task1"
sweetChildOMine.task2(); // prints "Base.task2"
Run Code Online (Sandbox Code Playgroud)

多么惊喜!你认为既然sweetChildOMine有一个实例的引用Child,sweetChildOMine.task2()应该打印"Child.task2"因为它被Child类重写了,对吧?

错误!一个static方法不能被覆盖!它只能被子类隐藏!事实上,如果你试图做正确的事情并添加@Override注释task2,它将无法编译!

JLS 15.12.4.4找到要调用的方法:

如果是调用模式static,则不需要目标引用,也不允许覆盖.类T的方法m是要调用的方法.

实际上,这个问题在Java Puzzlers Puzzle 48中有所涉及:我得到的只是静态.在这个难题的最后给出的结论是这样的:

总而言之,static使用类名限定方法调用,或者如果您从他们自己的类中调用它们,则根本不对它们进行限定,但从不使用表达式限定它们.另外,避免隐藏静态方法.总之,这些指南有助于消除静态方法的动态调度覆盖的误导性外观.

最好一起遵循所有这些建议,因此:

  • 如果您在static自己的类中调用方法,则不符合条件
  • 否则,符合班级名称
    • 如果你在一个班级中做了很多这样的事情,那么考虑一下static import这个特定的方法
      • 尽量不要向static import所有成员提供*
    • 永远不要用表达来限定
  • 不要隐藏static方法; 你不能@Override,它只会引起混乱

也可以看看: