当Java编译器内部有一个类“c”时,它是如何工作的?
考虑以下代码当Java编译器内部有一个类“c”时,它是如何工作的?,java,compilation,Java,Compilation,考虑以下代码 public class myClass{ myClass instanceOfNotYetDefinedClass; ... //etc code } 我不明白编译器是如何理解的:我告诉它创建一个类,然后它说:“好吧!让我看看这个myClass类有什么。哦,它是一个myClass,让我看看它有什么…”等等 这可能是一个非常愚蠢的问题,但我真的不明白如何处理这个问题。要了解编译器的功能,请使用javac编译该类并在其上运行javap。在课堂上这样做会产生以下效果:
public class myClass{
myClass instanceOfNotYetDefinedClass;
... //etc code
}
我不明白编译器是如何理解的:我告诉它创建一个类,然后它说:“好吧!让我看看这个myClass类有什么。哦,它是一个myClass,让我看看它有什么…”等等
这可能是一个非常愚蠢的问题,但我真的不明白如何处理这个问题。要了解编译器的功能,请使用javac编译该类并在其上运行javap。在课堂上这样做会产生以下效果:
public class myClass {
myClass instanceOfNotYetDefinedClass;
public myClass();
}
公共myClass()
是一个默认构造函数,与此处无关。从这里,我们可以看到编译器只是将类型为myClass
的字段附加到myClass
。这是怎么回事?由于myClass
是代码作用域中的现有类,编译器知道它将在运行时定义。因此,它只是将这一定义保持原样。在运行时,调用myClass.instanceOfNotYetDefinedClass
会为您提供字段的值-如果您不初始化它,则该值为null
,或者是具有自己字段的myClass
实例。这里没有无限递归或冲突,除非您在构造函数中调用new myClass()
。要查看编译器的功能,请使用javac编译类并在其上运行javap。在课堂上这样做会产生以下效果:
public class myClass {
myClass instanceOfNotYetDefinedClass;
public myClass();
}
公共myClass()
是一个默认构造函数,与此处无关。从这里,我们可以看到编译器只是将类型为myClass
的字段附加到myClass
。这是怎么回事?由于myClass
是代码作用域中的现有类,编译器知道它将在运行时定义。因此,它只是将这一定义保持原样。在运行时,调用myClass.instanceOfNotYetDefinedClass
会为您提供字段的值-如果您不初始化它,则该值为null
,或者是具有自己字段的myClass
实例。这里没有无限递归或冲突,除非您在构造函数中调用new myClass()
。编译器有多种方法可以做到这一点:
方法#1:对解析树进行两次传递:
- 在过程1中,查找所有声明和所有范围边界,并填充符号表1
- 在过程2中,找到所有标识符引用并根据符号表解析它们
- 每当遇到声明时,创建符号表项
- 遇到标识符引用时:
- 尝试在符号表中解析它
- 如果解决失败,请将其添加到稍后要解决的列表中
- 在过程结束时,重新访问列表中的所有标识符,并尝试根据(现在已完成的)符号表再次解析它们
对类本身的引用实际上更简单。在您的示例代码中,编译器将在看到使用
myClass
之前“查看”公共类myClass的解析树节点。因此,当遇到后者时,myClass
的条目将已经在符号表中
(在像C这样的老式语言中,函数的声明和定义可以是分开的,但是如果在编译单元的前面声明了标识符,则可以引用它。)
1-如果您不知道符号表是什么,那么有一些关于编译器和编译器构造的好教材。编译器可以通过多种方式实现这一点: 方法#1:对解析树进行两次传递:
- 在过程1中,查找所有声明和所有范围边界,并填充符号表1
- 在过程2中,找到所有标识符引用并根据符号表解析它们
- 每当遇到声明时,创建符号表项
- 遇到标识符引用时:
- 尝试在符号表中解析它
- 如果解决失败,请将其添加到稍后要解决的列表中
- 在过程结束时,重新访问列表中的所有标识符,并尝试根据(现在已完成的)符号表再次解析它们
对类本身的引用实际上更简单。在您的示例代码中,编译器将在看到使用
myClass
之前“查看”公共类myClass的解析树节点。因此,当遇到后者时,myClass
的条目将已经在符号表中
(在像C这样的老式语言中,函数的声明和定义可以是分开的,但是如果在编译单元的前面声明了标识符,则可以引用它。)
1-如果你不知道什么是符号表,那么有很多关于编译器和编译器构造的好书。Java是开源的,请看源代码。;-)编译器不会这样自言自语。Java是开源的,看看源代码。;-)编译器不会这样自言自语。