从Java 1.6开始,JVM不仅可以运行Java,还可以运行多种编程语言。我从概念上了解Java如何在Java VM上运行,但其他语言也无法在Java VM上运行。在我看来,这一切都像黑魔法。您是否有任何文章可向我指出,以便我可以更好地理解它们之间的关系?
从Java 1.6开始,JVM不仅可以运行Java,还可以运行多种编程语言。我从概念上了解Java如何在Java VM上运行,但其他语言也无法在Java VM上运行。在我看来,这一切都像黑魔法。您是否有任何文章可向我指出,以便我可以更好地理解它们之间的关系?
Answers:
关键是JVM的本地语言:Java字节码。可以将任何语言编译为JVM可以理解的字节码-您所需要做的就是发出字节码的编译器。从那时起,从JVM的角度来看并没有什么不同。如此之多,以至于您可以获取已编译的Scala,Clojure,Jython等类文件,并将其反编译(例如使用JAD)为普通的Java源代码。
您可以在以下文章/主题中找到关于此的更多详细信息:
我不了解Java 5或6 JVM中的任何根本变化,这些变化可能使其他语言(从其编译的代码)可以在其上运行或变得更加容易。在我的理解中,JVM 1.4在这方面或多或少地具有与JVM 6相同的能力(尽管可能有所不同;我不是JVM专家)。只是在十年的上半年,人们开始开发其他语言和/或字节码编译器,结果在2006年Java 6发布时开始出现(并广为人知)。
但是,所有这些JVM版本都有一些局限性:JVM本质上是静态类型的,并且直到发行版7,才支持动态语言。引入invokedynamic
新的字节码指令后,这种情况发生了变化,新的字节码指令使方法调用能够依赖于动态类型检查。
虚拟机(例如JVM)是一个程序,它接受一组简单的指令(通常很容易转换为真实的CPU指令)作为输入(通常是文件),并实际上将其编译并作为本机CPU指令运行(通常使用按需编译器(例如HotSpot或JIT)。
它本质上是抽象层。由于几个相似之处(例如基于堆栈),将VM指令集实现移植到不同的处理器体系结构通常要容易得多。将不同的编程语言移植到VM指令也容易得多,因为与原始CPU指令相比,它更面向现代编程语言。许多虚拟机(例如JVM和CLR(.NET))都包含有关调用虚拟方法和创建对象实例的指令。
让我们以一种语言为例。称之为MyLanguage。由于它是一种编程语言,因此最终可以编译为一些CPU体系结构指令集。因此,这意味着,在给定兼容,灵活的虚拟机指令集的情况下,还可以将MyLanguage编译为该VM的指令集。
效率总是存在问题,因为您可能需要破解VM指令集中的一些变通方法,而这些变通方法本来不是必须要做的,但是仍然有可能。
JVM是图灵完备的计算机(有限的内存除外),任何图灵完备的计算机(物理或虚拟)都可以执行任何编程语言(内存,性能和物理IO限制除外)。
片刻,您可以将JVM视为具有自己的指令集(例如x86)的处理器。处理器可以执行已编译为机器语言的C语言代码。如果对JVM应用相同的类比,则其他语言可以在JVM上执行,就像在其他处理器上一样,只要这些语言被编译成JVM的机器指令即可。JVM然后可以针对语言X运行这些指令。