java静态声明调用_java – 为什么在子类中调用在其超类中声明的静态方法时,不会调用一个子类静态初始化器?...

我认为它与jvm规范的

this part有关:

Each frame (§2.6) contains a reference to the run-time constant pool (§2.5.5) for the type of the current method to support dynamic linking of the method code. The class file code for a method refers to methods to be invoked and variables to be accessed via symbolic references. Dynamic linking translates these symbolic method references into concrete method references, loading classes as necessary to resolve as-yet-undefined symbols, and translates variable accesses into appropriate offsets in storage structures associated with the run-time location of these variables.

This late binding of the methods and variables makes changes in other classes that a method uses less likely to break this code.

在chapter 5年的jvm规范中,他们还提到:

作为以下结果,类或接口C可以被初始化:

The execution of any one of the Java Virtual Machine instructions new, getstatic, putstatic, or invokestatic that references C (§new, §getstatic, §putstatic, §invokestatic). These instructions reference a class or interface directly or indirectly through either a field reference or a method reference.

Upon execution of a getstatic, putstatic, or invokestatic instruction, the class or interface that declared the resolved field or method is initialized if it has not been initialized already.

在我看来,文档的第一位表明,任何符号引用都被简单地解决和调用,而不考虑它来自哪里。这个documentation about method resolution有以下说法:

[M]ethod resolution attempts to locate the referenced method in C and its superclasses:

If C declares exactly one method with the name specified by the method reference, and the declaration is a signature polymorphic method (§2.9), then method lookup succeeds. All the class names mentioned in the descriptor are resolved (§5.4.3.1).

The resolved method is the signature polymorphic method declaration. It is not necessary for C to declare a method with the descriptor specified by the method reference.

Otherwise, if C declares a method with the name and descriptor specified by the method reference, method lookup succeeds.

Otherwise, if C has a superclass, step 2 of method resolution is recursively invoked on the direct superclass of C.

所以从一个子类中调用它的事实似乎被忽略了。为什么这样做?在您提供的文档中,他们说:

The intent is that a class or interface type has a set of initializers that put it in a consistent state, and that this state is the first state that is observed by other classes.

在你的例子中,当Sub被静态初始化时,你会改变Super的状态。如果在调用Sub.staticMethod时发生初始化,那么您将获得与jvm认为相同的方法不同的行为。这可能是他们在谈论避免的不一致。

另外,这里是一些反编译的类文件代码,执行staticMethod,显示使用invokestatic:

Constant pool:

...

#2 = Methodref #18.#19 // Sub.staticMethod:()V

...

Code:

stack=0, locals=1, args_size=1

0: invokestatic #2 // Method Sub.staticMethod:()V

3: return

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值