java - java类文件加载/链​​接/初始化阶段的查询

标签 java class reflection

下面是代码:

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 Examplemain() 方法时,在计算表达式 Sub.class 并分配给 Class myClass 变量、class Superclass Sub加载链接,但未初始化>。这就是 class Superclass 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

我对类ExampleSuperSub的加载/链接/初始化阶段的理解正确吗?

最佳答案

参见JVMS §5.5

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 SpecificationThe Java® Virtual Machine Specification首先提出问题,如果您不理解某个部分,然后指向提出问题的部分。

关于java - java类文件加载/链​​接/初始化阶段的查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31216176/

相关文章:

java - 无法编译个人客户类,构造函数有问题吗?

java - Maven: fatal error 编译:无效的目标版本:1.8

php - 如何获取未实例化的类(类外)的类名?

python - 从列表中实例化一组类

wpf - 如何从 FrameworkElement 引发 Onload/OnUnload 事件以进行单元测试?

java - 三元运算符不能嵌套(squid :S3358) be configured

python - 从移动对象中获取的点列表

Java 字节码操作和 Java 反射 API?

swift - 泛型的最终自类,在方法签名中,在 Swift 中

java - 静态方法和实例方法的区别