静态方法调用
我们可以在不提及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.System
的static
字段访问,而不是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(); }
}