【问题标题】:Need clarification about compilation error and run-time error需要澄清编译错误和运行时错误
【发布时间】:2014-02-07 15:59:05
【问题描述】:

我正在阅读来自

的运行时错误和编译错误

Runtime vs Compile timeHow exactly does java compilation take place?

我可以推断的是,在编译期间,编译器不检查逻辑,而只检查语法和拼写错误,以及在运行时检查逻辑的位置以及如何实现这些等等。比如除以零,内存不够。

所以如果我的理解是正确的,那么只有在编译阶段才会出现编译错误,而只有在执行程序时才会出现运行时错误..

例如让我考虑一个简单的程序

public class Try {

public static void main(String[] args) {
    System.out.println("My first program");
    }
}

现在,当我在此阶段编译(即 javac )时,如果产生任何错误,则这些错误称为编译错误,在此期间会检查语法和拼写错误。

在将字节码转换为本机/机器码(例如 java )的过程中产生的错误称为运行时错误,在此过程中会检查程序逻辑。

因此,只有在执行开始时才会出现编译错误,而只有在第二阶段(即将字节码转换为机器码)时才会出现运行时错误。

如果我的理解有误请指正...

【问题讨论】:

  • “仅在执行开始时出现编译错误” - 否 - 仅在编译时出现。运行时错误 - 否 - 未转换为机器代码 - 运行程序时出现逻辑错误
  • 编译器做的不仅仅是语法检查。例如,它会进行类型检查,因此在执行之前会发现许多逻辑错误。

标签: java compiler-construction compiler-errors jvm


【解决方案1】:

一个简单的例子:

String myString = null;
myString.substring(..)

上面的代码在语法和类型上都是正确的,编译器没有显示错误。但是当您使用此代码执行程序(运行程序)时,会出现明显的运行时错误。编译器不够聪明,无法检测到这些错误,如果您想在开发周期的早期捕获这些错误(最好在您的客户端执行程序之前:P),可以使用静态分析工具之类的工具,或者更好的是自动测试。

【讨论】:

  • 只有在我们运行程序时才会出现运行时错误...哦!!不在这个阶段 java 很抱歉我不知道这个阶段的名字...
  • 也有编译器会对这样的结构发出警告(即进行一定量的静态分析),但这是一个很好的例子。
【解决方案2】:

不,典型的 Java 虚拟机不会将字节码转换为机器码。创建的字节码被解释。

如果您编写的程序从编程语言的角度正确(因此可以编译)但它做了一些不起作用的事情,就会发生运行时错误,例如尝试将某些内容除以零,或者程序是否要访问仅包含 3 个字符的字符串的第 4 个字符。

【讨论】:

  • “不,典型的 Java 虚拟机不会将字节码转换为机器码。创建的字节码会被解释。”解释和转换之间有什么区别..
  • 编译器创建“字节码”,它是用于假设的虚拟机的代码。 JVM 可以模拟这台机器(称为“解释”字节码),也可以使用即时编译器 (JIT) 将其转换为本机代码。
【解决方案3】:

你的理解是错误的,但不是很大。错误的名称几乎表明了它们的性质。

编译代码时发生编译时错误。编译意味着将文本转换为字节码。这意味着您的 java 代码无法转换为字节码。编译时错误通常会检查语法,尽管 Java 编译器也会进行一些非常基本的逻辑检查。例如,它不允许您使用无法访问的语句编译代码。

运行程序时发生运行时错误。这是 JVM 实际尝试执行编译的字节码并遇到问题的时候。没有将字节码直接转换为机器码的步骤。字节码由 JVM 直接解释。正如您所指出的,这些问题可能是除以零和其他未定义的操作、内存不足或有时试图将对象转换为非法类型。这些只是例子。任何阻止字节码执行的行为都被视为运行时错误。

【讨论】:

  • “此外,没有将字节码转换为机器码的步骤。”你的意思是纠正我说字节码被解释了......对!
  • @user2900314。从技术上讲,有一些方法可以将字节码转换为机器码,但它们通常不被使用,因为它们带走了使 Java 如此有用的二进制可移植性。当您运行标准 JVM 时,会解释字节码。
  • 最后我还有一个问题要问您...运行时错误仅在我们运行程序时发生...编译后,即 javac 我们得到一个类文件,它被解释为原生使用解释器(java )的/机器代码不是这个阶段称为运行..
  • 是的。除了机器码。 JVM (java) 解释并执行字节码命令。它不会将它们转换为本地应用程序意义上的机器代码。
猜你喜欢
  • 1970-01-01
  • 2022-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-24
相关资源
最近更新 更多