我看到here除了Java之外还有大量语言在JVM上运行。我对JVM中运行的其他语言的整个概念感到有点困惑。所以:
为JVM提供其他语言有什么好处?
为JVM编写语言/编译器需要什么(在高级术语中)?
如何使用JVM中的一种语言(Java除外)编写/编译/运行代码?
编辑:在接受的答案中回答了3个跟进问题(最初的评论)。他们在这里重印了易读性:
如果用JPython编写的应用程序如何与Java应用程序交互?
此外,JPython应用程序可以使用任何JDK函数/对象吗?
如果它是Jaskell代码,那么它是一种函数式语言会不会使它与JDK不兼容?
答案 0 :(得分:31)
分别解决三个问题:
为JVM提供其他语言有什么好处?
这里有两个因素。 (1)为什么JVM使用Java以外的语言,以及(2)为什么在JVM上运行另一种语言而不是运行不同的语言?
为JVM编写语言/编译器需要什么(在高级术语中)?
JVM读取字节码(.class)文件以获取它需要执行的指令。因此,任何要在JVM上运行的语言都需要编译为符合Sun specification的字节码。此过程类似于编译为本机代码,不同之处在于代码编译为由JVM解释的指令,而不是编译为CPU理解的指令。
如何使用JVM中的一种语言(Java除外)编写/编译/运行代码?
与在Java中编写/编译/运行代码的方式非常相似。为了让你的脚湿透,我建议你看看Scala,它在JVM上完美运行。
回答您的跟进问题:
如果用JPython编写的应用程序如何与Java应用程序交互?
这取决于实现选择弥合语言差距。在您的示例中,Jython project有一种直接的方法(see here):
from java.net import URL
u = URL('http://jython.org')
此外,JPython应用程序可以使用任何JDK函数/对象吗?
是的,见上文。
如果它是Jaskell代码,那么它是一种函数式语言会不会使它与JDK不兼容?
没有。例如,Scala(上面的链接)实现了功能特性,同时保持了与Java的兼容性。例如:
object Timer {
def oncePerSecond(callback: () => unit) {
while (true) { callback(); Thread sleep 1000 }
}
def timeFlies() {
println("time flies like an arrow...")
}
def main(args: Array[String]) {
oncePerSecond(timeFlies)
}
}
答案 1 :(得分:13)
您需要JVM上的其他语言,原因与您需要多种编程语言的原因相同:不同的语言更能解决不同的问题...静态打字与动态打字,严格与懒惰......声明性,势在必行,面向对象......等等。
通常,为JVM(或.Net CLR)上运行的另一种语言编写“编译器”本质上是将该语言编译为java字节码(或者在.Net,IL的情况下)的问题。汇编/机器语言。
也就是说,为JVM编写的许多额外语言都没有编译,而是解释为脚本语言...
答案 2 :(得分:6)
要考虑到这一点,请考虑设计一种新语言,并希望它在带有JIT和GC的托管运行时中运行。然后考虑你可以:
(a)编写您自己的托管运行时(VM)并解决各种技术难题,这些问题无疑会导致许多错误,性能不佳,线程不当以及大量的可移植性工作
或
(b)将您的语言编译为可以在Java VM上运行的字节码,该字符码已经非常成熟,快速并且在许多平台上得到支持(有时候有多种供应商选择可供选择)。
鉴于JavaVM字节码与Java语言没有太大的联系,以至于过度限制了您可以实现的语言类型,因此它一直是想要在VM中运行的语言的流行目标环境。
答案 3 :(得分:4)
Java是一种相当冗长的编程语言,在过去的5年中,所有新的花哨语言/框架都会很快过时。为了支持人们在语言中想要的所有花哨语法并保持向后兼容性,将更多语言添加到运行时更有意义。
另一个好处是它允许你运行一些用Ruby ala JRuby(又名Rails)或Grails(基本上是Railys上的Groovy)等编写的Web框架,在一个经过验证的托管平台上,很可能已经在许多公司生产,而不是而不是必须使用不像经过试验和测试的Ruby托管环境。
要编译其他语言,您只需转换为Java字节代码。
答案 4 :(得分:3)
我会回答,“因为Java sucks”但是又一次,也许是too obvious ...; - )
答案 5 :(得分:2)
为JVM提供其他语言的优势与为计算机提供其他语言的优势完全相同:虽然所有图灵完备语言在技术上可以完成相同的任务,但某些语言使某些任务比其他语言更容易。其他语言使其他任务更容易。由于JVM已经能够在所有(好的,几乎所有)计算机上运行,而且很多计算机实际上已经拥有它,我们可以获得“一次编写,随处运行”的好处,但不需要那个人使用Java。
为JVM编写语言/编译器与为真实机器编写语言/编译器没有什么不同。真正的区别在于你必须编译到JVM的字节码而不是机器的可执行代码,但这在宏观方案中确实是一个微小的差异。
在JVM中为Java以外的语言编写代码与编写Java没有什么不同,当然,除了您将使用不同的语言。您将使用某人为其编写的编译器进行编译(同样,与C编译器没有太大区别,从根本上说,并且几乎没有与Java编译器完全不同),并且您最终只能运行它就像你编译Java代码一样,因为一旦它在字节码中,JVM就无法分辨出它来自哪种语言。
答案 6 :(得分:2)
针对不同的任务量身定制不同的语言。虽然某些问题域完全符合Java语言,但有些域更容易用其他语言表达。此外,对于习惯于Ruby,Python等的用户来说,生成Java字节码并利用JDK类和JIT编译器的能力具有明显的好处。
答案 7 :(得分:2)
回答你的第二个问题:
JVM只是一个抽象的机器和执行模型。因此,使用编译器对其进行定位与编译器可能针对的任何其他机器和执行模型相同,无论是在硬件(x86,CELL等)还是软件(parrot,.NET)中实现。 JVM非常简单,因此它实际上是编译器的一个相当容易的目标。此外,实现往往具有相当不错的JIT编译器(用于处理javac生成的糟糕代码),因此您可以获得良好的性能而无需担心大量优化。
有几点需要注意。首先,JVM直接体现了java的模块和继承系统,因此尝试执行其他任何操作(多重继承,多次调度)可能会非常棘手并且需要复杂的代码。其次,JVM经过优化,可以处理javac产生的字节码。生成与此非常不同的字节码很可能会进入JIT编译器/ JVM的奇怪角落,这可能效率最低(最糟糕的是,它们可能会导致JVM崩溃或者至少会产生虚假的VirtualMachineError异常)。
答案 8 :(得分:1)
JVM可以做什么是由JVM的字节码(在.class文件中找到的)而不是源语言定义的。因此,更改高级源代码语言不会对可用功能产生实质性影响。
至于为JVM编写编译器需要什么,您真正需要做的就是生成正确的字节码/ .class文件。如何使用备用编译器编写/编译代码取决于所讨论的编译器,但是一旦编译器输出.class文件,运行它们与运行javac生成的.class文件没什么不同。
答案 9 :(得分:1)
Java已经在七个主要版本(从1.0到1.6)上积累了庞大的用户群。它的发展能力受限于为生产中运行的无数数百万行Java代码保留向后兼容性的需要。
这是一个问题,因为Java需要发展到:
向后兼容性的要求是保持竞争力的障碍。
如果将Java与C#进行比较,Java在成熟的,生产就绪的库和框架中具有优势,并且在语言功能和市场份额增加率方面具有劣势。这是您对比较两代成功语言的期望。
任何新语言都具有与C#在极端程度上与Java相比的优势和劣势。在语言功能方面最大化优势并最小化成熟库和框架方面的缺点的一种方法是为现有虚拟机构建语言,并使其与为该虚拟机编写的代码互操作。这就是Groovy和Clojure取得适度成功背后的原因;和斯卡拉周围的兴奋。如果没有JVM,这些语言在一个非常专业的细分市场中只会占据一席之地,而在JVM中,它们在主流中占据了重要的位置。
答案 10 :(得分:1)
因为JSR进程使Java变得越来越死:http://www.infoq.com/news/2009/01/java7-updated
令人遗憾的是,即使因为成员无法就实施达成一致,也不会添加像Closures这样的基本和长期已知的附加内容。
答案 11 :(得分:1)
编译器编写器生成JVM或CLR字节代码要容易得多。它们比任何机器语言都更清晰,更高级别的抽象。因此,尝试创建新语言比以往任何时候都更加可行,因为您所要做的就是针对这些VM架构中的一个,并且您将拥有一套已经可用于您的语言的工具和库。他们让语言设计师更专注于语言,而不是所有必要的支持基础设施。
答案 12 :(得分:1)
.NET语言更多用于展示而非实际用途。每种语言都是如此被屠杀,以至于他们都是新面孔的C#。
为Java VM提供替代语言有多种原因:
答案 13 :(得分:1)
这些其他语言的优势在于它们可以相对轻松地访问大量的Java库。
Java人员的优势因语言而异 - 每个人都有一个故事告诉Java编码员他们做得更好。有些人会强调如何使用它们为基于JVM的应用程序添加动态脚本,其他人只会谈论他们的语言如何更易于使用,语法更好等等。
编写任何其他语言编译器所需要的是相同的东西:解析为AST,然后将其转换为目标体系结构的指令(字节代码)并以正确的格式(.class文件)存储。
从用户的角度来看,您只需编写代码并运行编译器二进制文件,然后输出.class文件,您可以将它们与您的Java编译器生成的文件混合使用。
答案 14 :(得分:0)
在某种程度上,它可能是针对.NET CLR的“军备竞赛”。
但是我认为将新语言引入JVM也是有正当理由的,特别是当它们“并行”运行时,你可以使用正确的语言来完成正确的工作,像Groovy这样的脚本语言可能正是如此您需要进行页面演示,而常规旧Java更适合您的业务逻辑。
我要留下更有资格谈论编写新语言/编译器所需内容的人。
至于如何编写代码,你可以像往常一样在notepad / vi中进行编写! (或者如果你想以简单的方式进行操作,请使用支持该语言的开发工具。)编译将需要一个特殊的编译器来解释并将其编译成字节码。
由于java在技术上也会生成字节码,因此您无需执行任何特殊操作即可。
答案 15 :(得分:0)
原因是JVM平台提供了很多优势。
Sun试图通过他们的脚本规范(例如Python,Ruby)来支持的语言很多,而且很大程度上是因为他们认为提高了生产力。从理论上讲,运行Jython可以提高效率,并利用 Python 的功能来解决更适合Python的问题,但仍然能够在运行时级别与现有的集成代码库。 Python 和 Ruby 的经典实现对 C 库具有相同的能力。
此外,使用动态语言表达某些内容比使用Java更容易。如果是这种情况,你可以走另一条路;使用 Java 中的 Python / Ruby 库。
性能受到打击,但许多人愿意接受这一点,以换取更简洁,更清晰的代码库。
答案 16 :(得分:0)
他们这样做是为了跟上.Net。 .Net允许C#,VB,J#(以前),F#,Python,Ruby(即将推出)和c ++。我可能错过了一些。对于脚本人来说,可能是那里最重要的一个。