我对.java文件的编译顺序感到困惑。编译从哪里开始?文件的顶端?(还是)来自包含main的类?(或)公共课程?
--- * File Sample1.java *---
class A
{
public static void main(String args[])
{
String str[] = {""};
System.out.println("hi");
B.main(str);
}
}
class B
{
public static void main(String args[])
{
System.out.println("hello");
}
} 我的假设编译了"Sample1.java":
1)代码从顶部开始执行。所以A类是编译后的B类。
那么我如何考虑下面的代码编译呢?
--- * File Sample2.java *---
class A extends class B
{
int a;
}
class B
{
int b;
} 此外,我还有一个问题:
编译器为A创建一个默认构造函数,其中调用它的超类构造函数(类B),编译器放置的调用也是如此,或者只是JVM试图在运行时调用它。
发布于 2018-01-17 06:32:15
编译从文件的顶部开始,但它经历了几个阶段。当编译器第一次读取类时,它只检查它是否能够解析语法,并从它构建内部树。在以后的阶段,它将尝试解析符号,然后检查它们是否存在。
您的示例(对语法进行了更正--不能说“扩展类 B"):
class A extends B {
int a;
}
class B {
int b;
}工作正常,因为编译器在读取类B的文本时不需要知道第一阶段是否存在类A。在后面的阶段,当编译器试图从B解析符号class A extends B时,它会查找B,并且因为它已经读取了B类的文本,所以它会找到它并正确编译代码。
发布于 2018-01-17 07:04:31
我看到了以下令人讨厌的代码:
A.java
public interface A {
A ZERO = new B();
void f(A a);
}B.java
public class B implements A {
public f(A a) {
g();
}
void g() {
}}
编译在java源文件中进行:
本地包和导入提供其他类,这些类可能也需要编译。
编译后的产品是一个.class文件,包含字段名和方法名及其签名。它按字段名和方法名称及其签名引用导入的类。用经典的术语来说,它是一个.o / .obj对象文件,仍然需要某种形式的链接。在编译器检查的java中,导入的类是否正确使用。
这样做的缺点是,当稍后在此编译过程之外交换.class时(例如,它在库jar中),那么在运行时,jvm可能会出现错误异常。
正如上面的循环引用所演示的那样,java源代码的编译顺序是免费的。应用程序入口点main与此无关。
因此,编译是几个文件的广度优先进程,而不是一个深度优先进程,完全处理一个.java。它可以在一步内生成一个.class文件,但是必须将检查导入的方法签名推迟到编译导入之后。
由于有几个java编译器,所以不能说更多。
https://stackoverflow.com/questions/48294702
复制相似问题