我对Java等解释性语言在编译语言方面的优势感到困惑。
对于编译语言,解释性语言(如java)的优势的标准解释是,相同的.class文件可以在不同类型的机器体系结构上运行。这怎么能省你的工作?
对于每种不同的机器架构,您是否需要使用不同的编译器将相同的.class文件解释为机器语言?因此,如果您需要为每个不同的计算机体系结构使用不同的编译器来将相同的.class文件解释为机器代码,那么这如何为您节省任何工作?
为什么不直接创建一个编译语言,将.java源文件编译成机器语言。当然这需要一个不同的编译器来编译从每个机器架构的java源文件到机器语言,但是除了必须为每个机器编译从.class文件到机器语言的不同编译器之外,这又是什么呢? / p>
我的意思是这与编译语言相同 - 无论是将java源文件编译为机器代码还是将类文件编译为机器代码,每个机器架构都需要一个编译器。
感谢。
答案 0 :(得分:5)
首先,声称“Java被解释”,虽然它有一些基础,但实际上是非常误导的,如果你只是从头脑中删除这个概念,那可能是最好的。
Java在构建时从源代码编译为中间表示(类文件,字节码)。首次加载类时,大多数JVM实现(包括Oracle HotSpot和IBM J9)将经历一个短暂的解释阶段,但如果该类将以任何频率使用,那么动态编译器(JIT)将运行并编译为本机代码。 (有些JVM,比如JRockit,直接转到本机而没有解释器。)
我认为“为什么Java不直接编译为本机代码”是真正的问题。正如其他人所说,明显的答案是可移植性。但它比它更微妙:动态编译产生比静态编译更高质量的代码。当动态编译代码时,JIT知道没有静态编译器可以知道的东西:当前硬件的特征(CPU版本) ,步进水平,缓存行大小等),以及当前运行的属性(感谢在解释过程中收集的分析数据。)您的决策质量取决于您的信息质量;与静态编译器相比,动态编译器可以获得更多更好的信息,因此可以产生更好的代码。
此外,动态编译器可以执行静态编译器无法实现的优化。例如,动态编译器可以进行推测性优化,如果它们变得无效或者它们的假设后来变得不正确,则将它们退出。 (请参阅此处的“动态去优化”:http://www.ibm.com/developerworks/library/j-jtp12214/)。
答案 1 :(得分:2)
对于每种不同的机器架构,您不需要不同的机器架构 编译器将相同的.class文件解释为机器语言? 所以如果你需要为每台不同的机器使用不同的编译器 架构将同一个.class文件解释成机器码,如何 这可以节省你的工作吗?
以上陈述是您的核心误区。
应用程序开发人员编写编译为可在任何兼容Java虚拟机上运行的字节代码的Java代码。
Java虚拟机解释(并可能编译)此字节码并执行应用程序。这些JVM是为主要架构和操作系统开发的,例如Intel上的Windows / Mac / Linux。 JVM开发人员是一组相对较小的工程师,例如来自Oracle和Sun的工程师。
从应用程序开发人员的角度来看,他或她只需要编译一次,因为字节代码(在.class文件中)可以在兼容的JVM上执行。应用程序开发人员无需担心底层架构或操作系统;他们只需要针对JVM的体系结构。 JVM开发人员是处理底层的人。
答案 2 :(得分:0)
首先,Java是一种编译语言,也是一种解释型语言,因为你必须从.java编译为.class。
为了得到你的问题,Java(通过某种程度上)解释获得的优势是你只需要编译一次每个程序,并且它可以在任何计算机上运行,因为Java运行时环境(JRE),这是事先编译以匹配本地操作系统和体系结构,可以在没有(或最小化)进一步编译的情况下弥合这一差距。
然而,在未解释的语言中,您必须为每个操作系统和您希望它运行的每个体系结构编译每个程序,与仅为每个操作系统和体系结构编译JRE一次相比,这需要更多的工作量和总编译时间。编制每个单独的程序一次。
在每次运行时都有一种编译本地架构的语言是不切实际的,因为编译是一个相当密集的过程。 Python每次运行时都会编译(但是,像Java一样,它编译为运行时环境,而不是本地架构),它是最慢的语言之一。
希望这有助于澄清事情。
答案 3 :(得分:0)
我喜欢sowrd299的回答。我的两分钱:
另一方面,“提前编译多个目标”并不是一件完全疯狂的事情。 Afaik Windows Universal Apps以这种方式工作:它在同一个exe文件中是相同的应用程序,但实际上exe包含为80x86和ARM目标编译的代码。这样,一个应用程序看起来可以在Windows移动和桌面解决方案中移植,而无需进一步解释。