静态方法调用

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

是的你可以。 检查静态导入 。 您必须在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); 

在Java 5中引入。

是的,您可以在不提及类名的情况下调用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()); } } 

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


现在让我们问一下这是不是一个好主意。 除非你从它的类中调用static方法,否则通常省略类名不是一个好主意!

让我们首先关注static import 。 该指南引用:

那么什么时候应该使用静态导入? 非常谨慎! 只有在您试图声明常量的本地副本或滥用inheritance(Constant Interface Antipattern)时才使用它。 换句话说,当您需要频繁访问来自一个或两个类的静态成员时,请使用它。 如果过度使用静态导入function,它可能会使您的程序不可读且无法维护使用您导入的所有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" 

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

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

从JLS 15.12.4.4找到要调用的方法 :

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

实际上,这个问题在Java Puzzlers Puzzle 48中有所涉及:我得到的只是静态的。 这个难题结尾处给出的结论如下:

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

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

  • 如果您在自己的类中调用static方法,则不要限定
  • 否则,符合class级名称
    • 如果您在一个类中执行此操作,请考虑static import该特定方法
      • 尽量不要static import所有成员*
    • 永远不要用表达来限定
  • 不要隐藏static方法; 你不能@Override它,它只会引起混乱

也可以看看:

  • 为什么Java不允许覆盖static方法?
  • 你什么时候使用Java的@Override注释?为什么?

是的,添加到Brian Agnew,您也可以通过该类类型的实例调用静态方法。

是。

 class CallStaticMethodTest { public static void staticMethodOne() { System.out.println("Static method one"); } // Invoke from a non-static method public void instanceMethodOne() { staticMethodOne();// Calling static method without mentioning the class name } // Invoke from another static method: public static void staticMethodTwo() { staticMethodOne(); } } 

是的,你可以调用没有类名的静态方法。 例如,如果您在同一个类的另一个静态方法中调用它。

公共类TestStatic {

 static void hello() { System.out.println("Hello World"); } static void hello2() { hello(); System.out.println("Welcome to java"); } public static void main(String[] args) { hello2(); } 

}