我懂了 这里 除了 Java 之外,还有很多语言可以在 JVM 上运行。我对在 JVM 中运行的其他语言的整个概念有点困惑。所以:

为 JVM 使用其他语言有什么优势?

为 JVM 编写语言/编译器需要什么(高级术语)?

如何在 JVM 中用某种语言(Java 除外)编写/编译/运行代码?


编辑: 有 3 个后续问题(最初的评论)在已接受的答案中得到了回答。为了便于阅读,将它们重印在这里:

例如,用 JPython 编写的应用程序如何与 Java 应用程序交互?

另外,JPython 应用程序可以使用任何 JDK 函数/对象吗?

如果它是 Jaskell 代码怎么办,它是一种函数式语言,这一事实是否不会使其与 JDK 不兼容?

有帮助吗?

解决方案

分别解答你的三个问题:

为 JVM 使用其他语言有什么优势?

这里有两个因素。(1) 为什么 JVM 使用 Java 以外的语言,以及 (2) 为什么在 JVM 上运行另一种语言,而不是不同的运行时?

  1. 其他语言可以满足其他需求。例如,Java 没有内置支持 关闭, ,这个功能通常非常有用。
  2. 在 JVM 上运行的语言与在 JVM 上运行的任何其他语言都具有字节码兼容,这意味着用一种语言编写的代码可以与用另一种语言编写的库进行交互。

为 JVM 编写语言/编译器需要什么(高级术语)?

JVM 读取字节码 (.class) 文件来获取它需要执行的指令。因此,任何要在 JVM 上运行的语言都需要编译为遵循以下规则的字节码: 太阳规格. 。此过程类似于编译为本机代码,只不过代码不是编译为 CPU 理解的指令,而是编译为 JVM 解释的指令。

如何在 JVM 中用某种语言(Java 除外)编写/编译/运行代码?

与用 Java 编写/编译/运行代码的方式非常相似。为了让你的脚湿润,我建议看看 斯卡拉, ,它在 JVM 上完美运行。

回答您的后续问题:

例如,用 JPython 编写的应用程序如何与 Java 应用程序交互?

这取决于弥合语言差距的实现选择。在你的例子中, Jython 项目 有一个简单的方法可以做到这一点(看这里):

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)
  }
}

其他提示

您在 JVM 上需要其他语言的原因与您通常需要多种编程语言的原因相同:不同的语言更好地解决不同的问题......静态类型对比动态类型,严格类型与非类型类型懒惰的 ...声明式、命令式、面向对象...ETC。

一般来说,为另一种语言编写一个“编译器”以在 JVM(或 .Net CLR)上运行,本质上就是将该语言编译成 java 字节码(或在 .Net 的情况下,IL),而不是汇编成汇编/机器语言。

也就是说,许多为 JVM 编写的额外语言不是编译的,而是解释的脚本语言......

反过来,考虑一下您想要设计一种新语言,并且希望它在具有 JIT 和 GC 的托管运行时中运行。然后考虑一下你可以:

(a) 编写自己的托管运行时 (VM) 并解决各种技术难题,这些问题无疑会导致许多错误、性能不佳、线程不正确以及大量的可移植性工作

或者

(b) 将您的语言编译成可以在 Java VM 上运行的字节码,Java VM 已经相当成熟、快速并且受多种平台支持(有时有不止一种供应商实现选择)。

鉴于 JavaVM 字节码与 Java 语言的联系并没有那么紧密,以至于过度限制了您可以实现的语言类型,因此它一直是想要在 VM 中运行的语言的流行目标环境。

Java 是一种相当冗长的编程语言,随着过去 5 年中出现的所有新奇语言/框架,它很快就会过时。为了支持人们想要的语言中的所有奇特语法并保持向后兼容性,向运行时添加更多语言更有意义。

另一个好处是它可以让你运行一些用 Ruby ala JRuby(又名 Rails)或 Grails(本质上是 Groovy on Railys)等编写的 Web 框架。在一个经过验证的托管平台上,该平台可能已经在许多公司投入使用,而不必使用尚未经过尝试和测试的 Ruby 托管环境。

要编译其他语言,您只需将其转换为 Java 字节代码即可。

我会回答:“因为 Java 很糟糕” 但话又说回来,也许那就是 太明显了 … ;-)

为 JVM 使用其他语言的优势与为一般计算机使用其他语言的优势完全相同:虽然所有图灵完备的语言在技术上都可以完成相同的任务,但某些语言使某些任务比其他语言更容易,而其他语言则使其他任务更容易。由于 JVM 是我们已经能够在所有(好吧,几乎所有)计算机上运行的东西,而且很多计算机实际上已经拥有它,因此我们可以获得“一次编写,随处运行”的好处,但不需要那个使用Java。

为 JVM 编写语言/编译器与为真实机器编写语言/编译器没有什么区别。真正的区别在于,您必须编译为 JVM 的字节码而不是机器的可执行代码,但这实际上只是总体方案中的一个微小差异。

在 JVM 中为 Java 以外的语言编写代码实际上与编写 Java 没有什么不同,当然,除了您将使用不同的语言之外。您将使用某人为其编写的编译器进行编译(同样,从根本上讲,与 C 编译器没有太大区别,并且与 Java 编译器几乎没有什么不同),并且您最终将能够运行它就像编译 Java 代码一样,因为一旦它是字节码,JVM 就无法分辨它来自哪种语言。

不同的语言针对不同的任务而定制。虽然某些问题领域非常适合 Java 语言,但有些问题领域更容易用其他语言表达。此外,对于习惯 Ruby、Python 等的用户来说,生成 Java 字节码并利用 JDK 类和 JIT 编译器的能力具有明显的好处。

只回答你的第二个问题:

JVM只是一个抽象机器和执行模型。因此,使用编译器定位它与编译器可能定位的任何其他机器和执行模型相同,无论是在硬件(x86、CELL 等)还是软件(parrot、.NET)中实现。JVM 相当简单,因此它实际上是编译器相当容易的目标。此外,实现往往具有相当好的 JIT 编译器(以处理 javac 生成的糟糕代码),因此您可以获得良好的性能,而不必担心大量优化。

有几点需要注意。首先,JVM 直接体现了 java 的模块和继承系统,因此尝试做任何其他事情(多重继承、多重分派)可能会很棘手并且需要复杂的代码。其次,JVM 经过优化以处理 javac 生成的字节码类型。生成与此非常不同的字节码可能会进入 JIT 编译器/JVM 的奇怪角落,这在最好的情况下可能效率低下(在最坏的情况下,它们可能会导致 JVM 崩溃或至少给出虚假的 VirtualMachineError 异常)。

JVM 可以执行的操作是由 JVM 的字节码(您在 .class 文件中找到的内容)而不是源语言定义的。因此,更改高级源代码语言不会对可用功能产生重大影响。

至于为 JVM 编写编译器需要什么,您真正需要做的就是生成正确的字节码/.class 文件。如何使用备用编译器编写/编译代码在某种程度上取决于相关编译器,但是一旦编译器输出 .class 文件,运行它们与运行 javac 生成的 .class 文件没有什么不同。

这些其他语言的优点是它们可以相对轻松地访问大量 Java 库。

Java 人员的优势因语言而异——每种语言都有一个故事告诉 Java 程序员他们在哪些方面做得更好。有些人会强调如何使用它们向基于 JVM 的应用程序添加动态脚本,其他人只会谈论他们的语言如何更易于使用、具有更好的语法等等。

编写任何其他语言编译器所需的东西都是相同的:解析为 AST,然后将其转换为目标架构的指令(字节代码)并以正确的格式存储(.class 文件)。

从用户的角度来看,您只需编写代码并运行编译器二进制文件,然后生成 .class 文件,您可以将其与 java 编译器生成的文件混合在一起。

.NET 语言更多的是用于展示而不是实际用途。每种语言都已经被屠杀殆尽,以至于它们都是换了新面孔的 C#。

为 Java VM 提供替代语言有多种原因:

  • JVM 是多平台的。任何移植到 JVM 的语言都可以免费获得这一点。
  • 那里有相当多的遗留代码。ColdFusion 等过时的引擎性能更好,同时使客户能够缓慢地将其应用程序从遗留解决方案过渡到现代解决方案。
  • 某些形式的脚本更适合快速开发。例如,JavaFX 的设计考虑了快速图形开发。通过这种方式,它可以与 DarkBasic 等引擎竞争。(处理是这个领域的另一个参与者。)
  • 脚本环境可以提供控制。例如,应用程序可能希望向用户公开类似 VBA 的环境,而不公开底层的 Java API。使用像Rhino这样的引擎可以提供一个支持在仔细控制的沙箱中进行快速和脏编码的环境。
  • 解释的脚本意味着无需重新编译任何内容。无需重新编译即可转化为更加动态的环境。例如尽管 OpenOffice 使用 Java 作为“脚本语言”,但 Java 的使用效果很差。用户必须经历各种重新编译/重新加载循环,这在像 Javascript 这样的动态脚本环境中是不必要的。
  • 这让我想到了另一点。可以更轻松地停止和重新加载脚本引擎,而无需停止和重新加载整个 JVM。这增加了脚本语言的实用性,因为环境可以随时重置。

对于编译器编写者来说,生成 JVM 或 CLR 字节码要容易得多。它们是比任何机器语言更清晰、更高层次的抽象。因此,尝试创建新语言比以往任何时候都更加可行,因为您所要做的就是针对其中一个 VM 架构,并且您将拥有一组可用于您的语言的工具和库。它们让语言设计者更多地关注语言而不是所有必要的支持基础设施。

因为JSR进程正在让Java越来越死: http://www.infoq.com/news/2009/01/java7-updated

令人遗憾的是,即使是像闭包这样重要且众所周知的附加功能也不会仅仅因为成员无法就实现达成一致而被添加。

Java 已经通过七个主要版本(从 1.0 到 1.6)积累了庞大的用户基础。它的发展能力受到对生产中运行的无数行 Java 代码保持向后兼容性的需要的限制。

这是一个问题,因为 Java 需要发展到:

  • 与从 Java 的成功和失败中吸取教训的新型编程语言竞争。
  • 结合了编程语言设计的新进展。
  • 允许用户充分利用硬件的进步 - 例如多核处理器。
  • 修复一些引入意外问题的前沿想法(例如检查异常、泛型)。

向后兼容性的要求是保持竞争力的障碍。

如果将 Java 与 C# 进行比较,Java 的优势在于成熟、可用于生产的库和框架,而劣势在于语言特性和市场份额的增长率。这是您通过比较两种相隔一代的成功语言所期望的结果。

与 Java 相比,任何新语言都具有与 C# 相同的优点和缺点。最大化语言功能方面的优势并最小化成熟库和框架方面的劣势的一种方法是为现有虚拟机构建语言,并使其与为该虚拟机编写的代码可互操作。这就是 Groovy 和 Clojure 取得一定成功的原因;以及围绕 Scala 的兴奋。如果没有 JVM,这些语言只能在非常专业的细分市场中占据很小的利基市场,而有了 JVM,它们就在主流中占据了重要的利基市场。

他们这样做是为了跟上.Net 的步伐。.Net 支持 C#、VB、J#(以前)、F#、Python、Ruby(即将推出)和 c++。我可能错过了一些。对于脚本人员来说,其中最重要的可能是 Python。

在某种程度上,这可能是针对 .NET CLR 的“军备竞赛”。

但我认为向 JVM 引入新语言也有真正的原因,特别是当它们“并行”运行时,您可以使用正确的语言完成正确的工作,像 Groovy 这样的脚本语言可能正是您所需要的您的页面演示,而常规的旧 Java 更适合您的业务逻辑。

我将留下更有资格的人来讨论编写新语言/编译器所需的内容。

至于怎么写代码,就照常在notepad/vi中写吧!(如果您想以简单的方式进行操作,则可以使用支持该语言的开发工具。)编译将需要该语言的特殊编译器来将其解释并编译为字节码。

由于 java 从技术上讲也生成字节码,因此您无需执行任何特殊操作即可运行它。

原因是 JVM 平台提供了很多优势。

  • 数量庞大的图书馆
  • 更广泛的平台实施
  • 成熟的框架
  • 已经是您基础架构的一部分的旧代码

Sun 试图通过其脚本规范支持的语言(例如Python、Ruby)的崛起很大程度上是因为它们提高了生产力。理论上,运行 Jython 可以提高您的工作效率,并利用以下功能: Python 解决更适合 Python 的问题,但仍然能够在运行时级别与现有代码库集成。的经典实现 Python红宝石 效果相同的能力 C 图书馆。

此外,用动态语言表达某些内容通常比用 Java 更容易。如果是这种情况,你可以走另一条路;消耗 Python/Ruby 图书馆来自 爪哇.

虽然性能会受到影响,但许多人愿意接受这一点,以换取更简洁、更清晰的代码库。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top