'Example.class'指向的对象什么时候出现?

时间:2015-07-03 11:10:07

标签: java eclipse

以下是该计划:

package annotationtype;

public class Example {

    public static void main(String[] args){

    }
}

使用以下字节代码编译。

Classfile /D:/git/Java_programming/JavaCode/bin/annotationtype/Example.class
  ......
  Compiled from "Example.java"
public class annotationtype.Example
  .......
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Class              #2             // annotationtype/Example
   #2 = Utf8               annotationtype/Example
   #3 = Class              #4             // java/lang/Object
   ......
  #18 = Utf8               SourceFile
  #19 = Utf8               Example.java
{
  public annotationtype.Example();
  ........
  public static void main(java.lang.String[]);
  ......
}
SourceFile: "Example.java"

使用eclipse编辑器,在main()方法中,如果我输入,

Example.,eclipse编辑器立即提供class类型的Class<annotationtype.Example>成员

我的理解是,

低于字节代码,

#1 = Class              #2             // annotationtype/Example
 ..
#3 = Class              #4             // java/lang/Object

表示在Class<annotationtype.Example>的初始化阶段创建成员Class<annotationtype.Example> class所指向的class Example类型的对象,在功能上等同于

public class annotationtype.Example{
    public static Class<annotationtype.Example> class;
    {
        class = Class.forName("annotationtype.Example")
    }
    ......
}

我的理解是否正确,

Class<annotationtype.Example>类型的对象(创建)出现的阶段,Example.class指向的阶段?

1 个答案:

答案 0 :(得分:9)

您将Java编程语言的工件与包含Java字节代码的类文件的常量池项混淆。

type.class形式的类文字,以及对array.length形式数组长度的访问可能看起来像源代码中的成员访问,但与真实无关班级成员。

E.g。当您编写array.length时,它将被编译为字节码指令arraylength,专用于在运行时检索数组的长度,而无需实际指定JVM如何记住数组的长度。这取决于实现。

类文字更复杂。例如。当你写int.class时,没有什么可查询的。相反,编译器知道它必须读取static字段Integer.TYPE以获取运行时值以及该类文字的编译方式,作为对Integer.TYPE的字段访问。相比之下,引用类型的类文字是使用ldc指令编译的,该指令指向与字段无关的常量池条目。

类的常量池首先不包含Java对象。它包含链接信息。某些条目可能在首次使用时与Java运行时实例关联,但其工作方式是故意未指定的。这取决于JVM。这些条目用于不同的目的,即类条目可用于指定超类,实现的接口或类,其成员可通过方法调用或字段访问来访问。

这就是你的Example类文件包含这样一个Class条目的原因。它就在那里,因为该类使用它来描述自己。即使根本没有类文字Example.class。因此,描述类Class的{​​{1}}实例是创建when the class is loadedExample会记住所有已加载的类,并且在使用相同的加载器解析相同的名称时将使用它们。

请注意,当另一个类包含ClassLoader形式的类文字时,它将在其自己的常量池中拥有该类的自己的Class条目。类文本的运行时评估可以触发加载,从而在以前未加载时创建Example.class实例。否则,它将通过类加载器解析为已加载的类。