super class 中的受保护方法是否在不同包的 sub class 中可见?

Is protected method in super class visible in sub class in a different package?

看起来很傻,但我真的很困惑。请看下面的代码:

package com.one;
public class SuperClass {
    protected void fun() {
        System.out.println("base fun");
    }
}
----
package com.two;
import com.one.SuperClass;
public class SubClass extends SuperClass{
    public void foo() {
        SuperClass s = new SuperClass();
        s.fun(); // Error Msg: Change visibility of fun() to public 
    }
}

我也从 oracle 文档和 here 中读到,受保护的成员在另一个包的子 class 中也可见。所以 fun() 应该在包二的 SubClass 中可见。那为什么会报错?

我是不是漏掉了一些非常明显的东西?

受保护的方法只对内部的子类可见。如果您创建 SuperClass 的新实例,则您正在从外部访问它。

Java Language Specification

A protected member or constructor of an object may be accessed from outside the package in which it is declared only by code that is responsible for the implementation of that object.

这意味着,如果您在原始 class 的包之外编写子 class,则每个对象都可以调用 superclass 的受保护方法本身,但不在其他对象上。

在您的示例中,因为 sthis 是不同的对象,您不能调用 s.fun()。但是该对象将能够调用自身的 fun 方法 - 使用 this.fun() 或只是 fun()