从父类中调用main()方法

3

这里有一段代码:

class Test1{
    public static void main(String[] args){     
        System.out.println("Test1");
    }
}

class Test2 extends Test1{
}

当我尝试执行"java Test1"时,当然会得到以下结果:
Test1
但是,当我尝试执行"java Test2"时,仍会得到:
Test1
为什么?因为Test2类中不存在main()方法,而静态方法不会被继承。如果我在Test2中添加main()方法(使用字符串"Test2"代替"Test1"),那么我会得到:
Test2
我理解为什么在这个例子中会得到Test2,但不明白如果在类Test2中不存在main()方法时为什么会得到Test1。

6
谁告诉你的?静态方法无法被继承,但是它们可以像你在示例中清楚地看到的那样被继承屏蔽,只是无法被覆盖(它们不是多态的)。 - Pshemo
@KlemensMorbe 现在这是个谎言。 - Boris the Spider
可能是Java中静态方法被继承吗?的重复问题。 - Pshemo
当类加载器在类中找不到main()方法时,它会在父类中查找main()方法吗? - Too Strong Magic
我的上一个评论有错误:静态方法是隐藏的,而不是遮蔽的 - Pshemo
2个回答

3
静态方法是可以被继承的。请查看jls-8.4.8 Inheritance, Overriding, and Hiding。一个类C会从其直接超类和直接超接口中继承所有公共、受保护或者在与C相同包中默认访问权限的抽象和非抽象方法,只要它们没有被覆盖或隐藏。这段内容中没有提到不继承静态方法,因此你可以通过Test2类调用在Test1中声明的main方法(它被继承了)。

此外,来自 jls-8.4.8.2 隐藏(通过类方法)

如果一个类声明了一个静态方法 m,则声明中的 m 被称为隐藏任何方法 m',其中 m 的签名是 m' 的子签名 (§8.4.2),在类的超类和超接口中,否则代码可以访问类中。

因此,当您在 Test2 类中创建新的 main 方法时,您隐藏了(而不是覆盖)Test1.main 方法,这就是为什么您看到输出结果的原因。

Test2

谢谢。如果我理解正确的话,创建类对象时,Test2会从Test1继承静态方法main()。如果不显式地创建它,则会调用继承的方法。 - Too Strong Magic

2

静态方法实际上是可以被继承的,这就是这里发生的事情。例如,以下代码可以正常工作:

class Base {
    public static void saySomething() {
        System.out.println("Hi!");
    }
}

class Extended extends Base {
    public static void main(String[] args) {
        saySomething();
    }
}

谢谢。然而,现在这并不重要。我尝试理解为什么调用了父类中的方法而不是错误。 - Too Strong Magic
1
你为什么会期望出现错误?JVM在Test2的继承树中查找main方法并找到了一个。 - Mike Thomsen
在写这篇评论时,我还没有理解这个。 :) - Too Strong Magic

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接