静态方法调用

2022-09-02 19:16:19

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


答案 1

是的,您可以。查看静态导入。您必须在语句中提及类名,但之后您不必这样做。从链接的文章中:import

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 中引入。


答案 2

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

下面的代码按预期进行编译和打印。"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());
   }
}

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


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

让我们首先关注。引用指南中的一句话:static import

那么什么时候应该使用静态导入呢?非常谨慎!仅当您试图声明常量的本地副本或滥用继承(常量接口反模式)时,才使用它。换句话说,当您需要频繁访问一个或两个类中的静态成员时,请使用它。如果过度使用静态导入功能,它可能会使程序不可读且不可维护,从而用导入的所有成员污染其命名空间。你的代码的读者(包括你,在你写完代码几个月后)将不知道静态成员来自哪个类。从类中导入所有静态成员可能对可读性特别有害。如果只需要一个或两个成员,请单独导入它们。如果使用得当,静态导入可以通过删除类名重复的样板,使程序更具可读性。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"

真是惊喜!你可能会认为,既然有对 实例的引用,应该打印,因为它被类覆盖了,对吧?sweetChildOMineChildsweetChildOMine.task2()"Child.task2"Child

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

JLS 15.12.4.4 找到要调用的方法

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

事实上,这个问题在Java Puzzlers Puzzle 48:All I Get Is Static中已经涉及。在拼图结束时给出的结论是这样的:

总之,使用类名限定方法调用,或者如果从方法调用自己的类中调用它们,则根本不限定它们,但从不用表达式限定它们。此外,请避免隐藏静态方法。总之,这些准则有助于消除使用静态方法的动态调度进行重写的误导性外观。static

最好同时遵循所有这些建议,因此:

  • 如果要在某个方法自己的类中调用该方法,请不要限定static
  • 否则,请使用类名进行限定
    • 如果你在一个类中经常这样做,请考虑该特定方法static import
      • 尽量不要向所有成员提供static import*
    • 从不使用表达式限定
  • 不要隐藏方法;你不能,它只会引起混乱static@Override

另请参阅: