为什么我可以从 child 实例访问我的超级 class 的静态方法?

Why can I get access to static method of my super class from child instance?

为什么可以从 child 实例访问我的超级 class 的静态方法?

public class Test {

    public static void main(String[] args) {
        new UtilImpl().fun();
        new AbstractUtil() {}.fun();
    }

    static abstract class AbstractUtil {
        public static void fun() {
            System.out.println("Fun!");
        }
    }

    static class UtilImpl extends AbstractUtil {
    }

}

我同意从 parent class 的实例访问 parent class 的静态方法。但是如果我实例化一个 child class,那么访问 parent class.

的静态上下文是很奇怪的

PS

在实例上调用静态方法有什么好处?

这叫做继承。子 class 继承父 class 的 public 成员,包括 static 方法。重要的是 static 方法没有绑定到任何实例。你可以这样做:

UtilImpl.fun();
AbstractUtil.fun();

对于编译器来说,都是一样的。唯一的区别是您的代码创建了对象,但这些对象与调用方法的方式无关(另外正如@Dici 在评论中所说的那样,您还应该从编译器那里得到警告)。

在Java中,允许使用实例变量调用静态方法。这是在 JLS section 8.4.3.2 中定义的,引用:

A method that is declared static is called a class method.

A class method is always invoked without reference to a particular object.

在这种情况下,Java实际上会丢弃您使用的实例并调用静态方法。

Example 15.12.4.1-1 表达如下:

When a target reference is computed and then discarded because the invocation mode is static, the reference is not examined to see whether it is null:

class Test1 {
    static void mountain() {
        System.out.println("Monadnock");
    }
    static Test1 favorite(){
        System.out.print("Mount ");
        return null;
    }
    public static void main(String[] args) {
        favorite().mountain();
    }
}

which prints:

Mount Monadnock

Here favorite() returns null, yet no NullPointerException is thrown.