Java 为什么我可以从子实例访问我的超类的静态方法?
为什么可以从子实例访问我的超类的静态方法Java 为什么我可以从子实例访问我的超类的静态方法?,java,static-methods,Java,Static Methods,为什么可以从子实例访问我的超类的静态方法 public class Test { public static void main(String[] args) { new UtilImpl().fun(); new AbstractUtil() {}.fun(); } static abstract class AbstractUtil { public static void fun() { S
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 {
}
}
我同意从父类的实例访问父类的静态方法。但是如果我实例化一个子类,那么访问父类的静态上下文就很奇怪了
PS
在实例上调用静态方法有什么好处?它被称为继承。子类继承父类的
public
成员,包括static
方法。重要的是静态
方法不绑定到任何实例。你可以这样做:
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 {
}
}
UtilImpl.fun();
AbstractUtil.fun();
就编译器而言,这是一样的。唯一的区别是代码创建了对象,但这些对象与方法的调用方式无关(正如@Dici在评论中所说的那样,您还应该从编译器那里得到警告)。在Java中,允许使用实例变量调用静态方法。这在JLS中定义,引用: 声明为静态的方法称为类方法 类方法总是在不引用特定对象的情况下被调用。 在这种情况下,Java实际上会丢弃您使用的实例并调用静态方法 用以下方式表示: 由于 调用模式是静态的,不检查引用以查看 是否为空:
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();
}
}
其中打印:
Mount Monadnock
此处favorite()返回null,但不会引发NullPointerException
为什么?因为它是这样指定的。但是,你会得到一个警告。这个主题已经被很好地介绍过了,这里有一些例子和解释:这个问题其实并不是无趣的,检查一下我链接的问题。他也在从实例调用静态方法,您可能希望在此基础上添加一些内容,这意味着编译器将重写要在
类上执行的调用,对吗?为什么他们允许这样做?我宁愿给出这个事实,因为我知道规范。这里最有趣的问题是为什么Java创建者使用此功能。根据链接上的规范,静态方法不会从超级接口继承(可能是为了避免多继承冲突)。我想知道这种类继承的优点是什么。有趣是的,很有趣。