Inheritance in Static Methods
为什么下面的代码会打印"MAIN"?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| public class Main
{
public static void method ()
{
System. out. println("Main");
}
public static void main (String[] args )
{
Main m = new SubMain ();
m. method();
}
}
class SubMain extends Main
{
public static void method ()
{
System. out. println("SubMain");
}
} |
在运行时,m指向Submain的一个实例,因此它在概念上应该打印"submin"。
- 甚至可以编写Main m = null;,然后调用该方法,在点之前的表达式根本不用。
静态方法根据变量的编译时类型进行解析。m是Main类型,因此调用Main中的方法。
如果将其更改为SubMain m ...,则将调用SubMain上的方法。
- 除了这个答案,我建议您不要从实例对象调用静态方法,也不要从类名调用它们(例如:submin.method(),而不是m.method())。
- 这就是为什么Java试图在实例对象上调用静态方法时警告您的原因。
- "Erim装修Java不警告你,但你的IDE会警告你。
这是因为静态方法不是多态的。此外,静态方法不应该由对象调用,而应该使用类,即Main.method()或SubMain.method()来调用。当你调用EDCOX1,11时,Java实际上调用EDCOX1×6,因为M是MyType。
如果你想享受多态性,不要使用静态方法。
当我尝试做这种事情时,Eclipse会给我这样的警告:
The static method XXX() from the type XXX should be accessed in a static way
静态方法不参与继承。变量的类型为Main,因此编译器将函数调用解析为Main.method()。
为了增加乐趣,尝试将m设置为null。
Java对静态方法执行早期绑定,不同于动态绑定的实例方法。
因为对象变量的类型是main,所以调用在编译时绑定到超类实现。
这里有一个很好的解释。
静态方法与类名静态绑定,因为m是主类的类型然后在编译之后,它看起来如下主要方法。在你的课程汇编之后运行以下命令JAVAP—C主您可以看到主类的JVM程序集代码你会看到下面m.method//调用静态invoke static,invoke special告诉静态绑定invoke special,invoke接口告诉动态绑定