为什么以下代码打印“Main”?
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
的实例,因此它应该在概念上打印“SubMain”。
答案 0 :(得分:18)
静态方法在变量的编译时类型上得到解析。 m
的类型为Main
,因此调用Main
中的方法。
如果您将其更改为SubMain m ...
,则会调用SubMain
上的方法。
答案 1 :(得分:15)
这是因为静态方法不是多态的。此外,静态方法不应该由对象调用,而是使用类,即Main.method()
或SubMain.method()
。
当您调用m.method()
时,java实际上会调用Main.method()
,因为m是Main类型。
如果你想享受多态,请不要使用静态方法。
答案 2 :(得分:2)
应该以静态方式访问XXX类型的静态方法XXX()
静态方法不参与继承。变量的类型为Main
,因此编译器将函数调用解析为Main.method()
。
为了增加乐趣,请尝试将m
设置为null
。
答案 3 :(得分:1)
答案 4 :(得分:0)
静态方法与其类名静态绑定,因为m是Main类的类型 然后在编译之后它看起来如下 Main.method(); 编译完课程后 运行以下命令 javap -c Main 你可以看到Main类的jvm汇编代码 你会看到以下 m.method //调用静态 调用static,调用special告诉静态绑定 调用special,invoke接口告诉动态绑定