首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >编译从哪里开始?文件的顶端?(还是)来自包含main的类?(或)公共课程?

编译从哪里开始?文件的顶端?(还是)来自包含main的类?(或)公共课程?
EN

Stack Overflow用户
提问于 2018-01-17 06:17:00
回答 2查看 75关注 0票数 1

我对.java文件的编译顺序感到困惑。编译从哪里开始?文件的顶端?(还是)来自包含main的类?(或)公共课程?

代码语言:javascript
复制
--- * 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类。

那么我如何考虑下面的代码编译呢?

代码语言:javascript
复制
--- * File Sample2.java *---
class A extends class B
{ 
int a; 
} 
class B 
{
int b; 
} 

此外,我还有一个问题:

编译器为A创建一个默认构造函数,其中调用它的超类构造函数(类B),编译器放置的调用也是如此,或者只是JVM试图在运行时调用它。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-01-17 06:32:15

编译从文件的顶部开始,但它经历了几个阶段。当编译器第一次读取类时,它只检查它是否能够解析语法,并从它构建内部树。在以后的阶段,它将尝试解析符号,然后检查它们是否存在。

您的示例(对语法进行了更正--不能说“扩展 B"):

代码语言:javascript
复制
class A extends B { 
    int a; 
} 
class B {
    int b; 
}

工作正常,因为编译器在读取类B的文本时不需要知道第一阶段是否存在类A。在后面的阶段,当编译器试图从B解析符号class A extends B时,它会查找B,并且因为它已经读取了B类的文本,所以它会找到它并正确编译代码。

票数 3
EN

Stack Overflow用户

发布于 2018-01-17 07:04:31

我看到了以下令人讨厌的代码:

A.java

代码语言:javascript
复制
public interface A {
    A ZERO = new B();
    void f(A a);
}

B.java

代码语言:javascript
复制
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编译器,所以不能说更多。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48294702

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档