关于java:对解释语言的优势感到困惑

Confused about advantage of interpreted language

我对像Java这样的解释语言优于编译语言感到困惑。

解释语言(如Java)优于编译语言的标准解释是相同的.class文件可以在不同类型的机器体系结构上运行。这怎么能帮你省去任何工作?

对于每个不同的机器体系结构,是否需要不同的编译器来将同一个.class文件解释为机器语言?因此,如果您需要为每个不同的机器体系结构使用不同的编译器将同一个.class文件解释为机器代码,那么这将如何为您节省任何工作呢?

为什么不只是编写一个编译语言,将.java源文件立即编译成机器语言。当然,这需要一个不同的编译器从Java源文件编译到每种机器体系结构的机器语言,但是这又如何比每个机器从一个类文件编译成一个机器语言都需要一个不同的编译器?

我的意思是,这和编译语言是一样的——无论是编译Java源文件到机器代码还是将类文件编译成机器代码,每个机器体系结构都需要一个编译器。

谢谢。


首先,"Java被解释"这一说法虽然有一定的根据,但却很容易误导人,如果你只是从头脑中删除这个概念,那也许是最好的。

在编译时,Java从源代码编译为中间表示(类文件、字节码)。第一次加载类时,大多数JVM实现(包括Oracle Hotspot和IBM J9)将经历一个短暂的解释阶段,但如果该类将以任何频率使用,则将运行动态编译器(JIT)并编译为本机代码。(一些JVM,如Jrockit,直接转到本机,不带解释器。)

我认为"为什么Java不直接编译成本地代码"是这里真正的问题。正如其他人所说,显而易见的答案是可移植性。但它比这更微妙:动态编译产生的代码质量比静态编译高。当动态编译代码时,JIT知道没有静态编译器能够知道的事情:当前硬件的特性(CPU版本、步进级别、缓存线大小等)以及当前运行的属性(由于在解释过程中收集了分析数据)。您的决策的质量取决于对于您的信息,动态编译器比静态编译器有更多更好的可用信息,因此可以生成更好的代码。

此外,动态编译器有可能执行任何静态编译器都无法想象的优化。例如,动态编译器可以进行推测性的优化,如果结果是无效的,或者假设后来变得不正确,则可以将其退出。(请参阅"动态去优化"这里:http://www.ibm.com/developerworks/library/j-jtp2214/)。


For each different machine architecture, wouldn't you need a different
compiler to interpret the same .class file into the machine language?
So if you need a different compiler for each different machine
architecture to interpret the same .class file into machine code, how
does this save you any work?

以上陈述是你的核心误解。

应用程序开发人员将Java代码编译为可以在任何兼容Java虚拟机上运行的字节代码。

Java虚拟机解释(并且可能编译)该字节码并执行应用程序。这些JVM是为主要的体系结构和操作系统开发的,例如英特尔的Windows/Mac/Linux。JVM开发人员是一个相对较小的工程师组,例如来自Oracle和Sun的工程师。

从应用程序开发人员的角度来看,他或她只需要编译一次,因为字节代码(在.class文件中)可以在兼容的JVM上执行。应用程序开发人员不需要担心底层体系结构或操作系统;他们只需要针对JVM的体系结构。JVM开发人员是处理底层的开发人员。


我喜欢索德299的回答。我的两分钱:

  • 在技术上,您有无数不同的目标体系结构
  • 因此,同时为所有目标编译代码并将其打包在一起将导致无限大的可执行文件
  • 因此,编译Java对虚拟机字节码是一个更好的解决方案:因为它只有一个目标架构的足迹。
  • 虽然开发人员可以单独为所有新的和旧的架构添加JVM,但允许新的新组件(如树莓PI)运行您在上个世纪编译的Java代码。

另一方面,"提前编译多个目标"并不是完全疯狂的事情。Afaik Windows通用应用程序是这样工作的:它是同一个exe文件中的同一个应用程序,但实际上该exe包含为80x86和ARM目标编译的代码。这样一来,一个应用程序看起来可以在Windows Mobile和桌面解决方案之间移植,而无需进一步解释。


首先,Java是一种编译语言,也是一种解释语言,因为您必须从.java编译到.class。

为了得到问题的答案,Java(通过某种解释)获得的优势是,只需要编译每个程序一次,它就可以在任何计算机上运行,因为预先编译的Java运行环境(JRE)可以与本地OS和体系结构相匹配,可以在没有(或最少)进一步编译的情况下弥补这一差距。

然而,在一种未解释的语言中,您必须为每个操作系统编译每个程序以及要运行它的每个体系结构,这比为每个操作系统和体系结构编译一次JRE和只编译一次单个程序需要花费更多的精力和总的编译时间。

因为编译是一个相当密集的过程,所以让一种语言在每次运行时都为本地架构编译是不切实际的。Python每次运行时都会编译(虽然像Java一样,它编译的是运行时环境,而不是本地体系结构),它是最慢的语言之一。

希望这有助于解决问题。