下面是代码:
package packagename;
import java.lang.reflect.Method;
class Super{
static{
System.out.println("Super");
}
public void superMethod(){
}
}
class Sub extends Super{
static{
System.out.println("Sub");
}
public void subMethod(){
}
}
public class Example {
static{
System.out.println("In Example");
}
public static void main(String[] args){
Class myClass = Sub.class;
Method[] methods = myClass.getMethods();
for(Method eachMethod : methods){
System.out.println(eachMethod.getName() + " with " + eachMethod.getParameterCount() + " parameters");
}
}
}
编译此代码并执行时,
> java 示例
,
类示例
被加载\链接\初始化。当 Java 解释器开始解释 class Example
的 main()
方法时,在计算表达式 Sub.class
并分配给 Class myClass
变量、class Super
和 class Sub
已加载和链接,但未初始化>。这就是 class Super
和 class Sub
的静态初始化 block 未执行的原因,如下输出所示。
In Example
subMethod with 0 parameters
superMethod with 0 parameters
wait with 0 parameters
wait with 2 parameters
wait with 1 parameters
equals with 1 parameters
toString with 0 parameters
hashCode with 0 parameters
getClass with 0 parameters
notify with 0 parameters
notifyAll with 0 parameters
我对类Example
、Super
和Sub
的加载/链接/初始化阶段的理解正确吗?
最佳答案
5.5. Initialization
Initialization of a class or interface consists of executing its class or interface initialization method (§2.9).
A class or interface C may be initialized only as a result of:
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 new instruction, the referenced class is initialized if it has not been initialized already.
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.
The first invocation of a java.lang.invoke.MethodHandle instance which was the result of method handle resolution (§5.4.3.5) for a method handle of kind 2 (REF_getStatic), 4 (REF_putStatic), 6 (REF_invokeStatic), or 8 (REF_newInvokeSpecial). This implies that the class of a bootstrap method is initialized when the bootstrap method is invoked for an invokedynamic instruction (§invokedynamic), as part of the continuing resolution of the call site specifier.
Invocation of certain reflective methods in the class library (§2.12), for example, in class Class or in package java.lang.reflect.
If C is a class, the initialization of one of its subclasses.
If C is an interface that declares a non-abstract, non-static method, the initialization of a class that implements C directly or indirectly.
If C is a class, its designation as the initial class at Java Virtual Machine startup (§5.2).
Prior to initialization, a class or interface must be linked, that is, verified, prepared, and optionally resolved.
一般来说,行为都有规范。如果想了解详情,可以考虑学习The Java® Language Specification和 The Java® Virtual Machine Specification首先提出问题,如果您不理解某个部分,然后指向提出问题的部分。
关于java - java类文件加载/链接/初始化阶段的查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31216176/