Java的新发展将如何影响其与Scala和Clojure等语言的互操作性?


11

据我了解,Scala和Clojure都被设计为新的语言,

  1. 取决于JVM,并且
  2. 从某种意义上说,它们可以轻松地与Java代码集成,因为它们允许在Scala和Clojure代码中使用Java类。

从Java 8开始(或者在后续的Java版本中可能更强大),Java语言的语义将发生变化。

我想问一下这些变化将如何影响Java与Scala / Clojure之间的互操作性,以及将会带来什么后果。例如,由于Java 8中的lambda不是对象(请参见here),所以Scala和Clojure可能必须处理不是对象的Java值。这会是个问题吗?

我可以想到以下情形:

  1. Scala或Clojure语言将得到扩展,以适应新的Java语义(以处理新的非对象值)并支持与Java的互操作性。
  2. Scala或Clojure语言将不会扩展。仅当新的Java功能(例如函数值)可以映射到现有概念时,这才有可能。例如,在Scala中,甚至函数都是对象,因此我猜Java函数在对Scala可见时会再次被包装到某种对象中。
  3. Scala或Clojure语言将继续支持直至Java 6或7的互操作性,而无需关注Java的最新发展。这将要求仍旧支持Java的较早版本(至少由OpenJDK或其他项目支持),以便这些语言可以基于Java的更为保守/稳定的分支。

总结:我们可以期望Java的未来发展会对Scala和Clojure等语言产生影响,以保持与Java的互操作性吗?已经有一些(链接到)有关此主题的正在进行的讨论吗?

注意

我可以想象Scala,Clojure和其他基于JVM的语言在将其实现更新到较新版本的JVM时不会有任何重大问题(并且新的JVM功能将使此实现更加容易)。我的问题集中在Java语言的功能以及其他JVM语言是否能够/如何“看到” /使用这些新功能,而不是基于JVM的语言是否可以在最新的JVM上运行。


6
说Scala等依赖Java是不精确的。它们取决于JVM字节码。所有的互操作性功能都处理字节码,而不处理Java语言源代码,因此对Java本身所做的任何更改都不会构成威胁。只有对JVM所做的更改才能影响这些语言,并且JVM非常保守-它从不删除对任何内容的支持。实际上,当今JVM中的大多数更改都是专门针对较新的动态语言的。
Kilian Foth,

@Kilian Foth:据我所知,Scala String是Java String。因此,Scala使用某些Java库类。但是,如果您认为该公式太强,我可以更改其公式。
Giorgio 2013年

@Kilian Foth:我删除了“ 取决于 ”一词,因为我的问题的重点在于Scala和Java resp之间的互操作性。Clojure和Java。
Giorgio 2013年

@KilianFoth这应该是一个答案,因为它解决了该问题的主要问题。任何新Java版本的首要目标都是向后兼容。
maple_shaft

3
@maple_shaft:我已更正了我的问题,并删除了“依赖”一词。正如我在另一条评论中指出的那样,我的问题不是Scala或Clojure如何依赖Java或JVM功能,而是Scala / Clojure如何“看到” Java功能。据我所知,他们可以看到Java 6特性,例如类,接口,对象,方法,原始数据类型。这允许Scala / Clojure使用(调用)Java 6代码。我的问题是,这些语言是否还会“看到”(并因此能够使用)将来的Java语言构造,或者这是否需要扩展Scala / Clojure语言?
乔治

Answers:


15

实际上,Java 8并没有引入太多对与Java互操作的其他JVM语言有害的信息。在Lambda上完成的工作帮助解决了许多有关invokedynamic,MethodHandles,MethodReferences等的小问题-但除此之外,它仍然可以正常进行。就是说,现在有许多其他JVM语言可以调用的全新API。他们将默认使用或不使用哪个取决于他们。

影响互操作性的最大变化实际上是Java 7引入的-允许在JVM中进行动态/后期绑定调用的invokedynamic字节码-最初是为JVM上的其他语言设计的。从那以后,它非常有用地适合Lamdbas,因此从Java 8开始,Java实际上将开始发出这些字节码。

一些语言(例如JRuby)已经大量使用invokedynamic,而另一些语言(Scala,Groovy等)仍在研究其使用或处于修补的早期阶段。理论上,它使它们的动态调用几乎与现有的性能一样Java调用静态调用,而不是过去不得不使用的许多较慢的变通方法。

随着项目Jigsaw进入平台,Java 9将为JVM语言带来更多挑战,这将成为传统上JVM的类加载和类路径的终结。JVM语言人员非常了解这一点,我希望可以进行一些明智的合作。


1
但是,据我所知,Scala闭包是一个对象。
Giorgio

1
是的 斯卡拉最近才刚刚下跌对Java 1.5的支持,这将是一个漫长,直到累倒1.6倍。
约尔格W¯¯米塔格

1
@Giorgio Java的语言功能无关紧要,因为无论如何,大多数这些功能等同于字节码技巧。如果我们接受JVM将始终向后兼容,即使引入了新的字节码,那么Scala将不受影响,可以选择在方便时利用这些新的JVM功能。
maple_shaft

1
“ Java的语言特性无关紧要,因为无论如何,大多数语言等同于字节码技巧。”:如果另一种语言想要使用Java构造,则它必须能够识别为该构造生成的字节码。如果Java引入了映射到新字节码的新结构,则主机语言至少应实现一个新的包装器/接口,以识别和使用新的字节码。例如,如果Java 8 lambda没有创建对象,而是创建了具有新的特定字节码的某种新构造,则必须对宿主语言进行修改以识别该对象。
Giorgio 2013年

2
@Giorgio:可以,但是没有计划对Java 8平台进行此类更改。事实上,JVMS只延长两次在Java平台的整个历史,在2003年和2010年,而第二次(引进的invokedynamic字节码)是专门为支持语言其他比Java; 实际上,Java 7语言支持或不使用该字节码。
约尔格W¯¯米塔格

2

当Java添加lambda时,Scala会被抛在后面,因为Java lambda会根据其所使用的上下文来分配类型,而Scala lambda会根据其参数,参数类型和返回类型来分配类型,例如,

executor.execute(() -> { System.out.println("hello world"); });

从Java 8可以用Scala编写为:

executor execute new Runnable {
    override def run() { println("hello world") }
}

除非您使用/编写一些将Scala()=> Unit转换为Runnable的包装器。


感谢您的回答,也感谢您回答我的问题(+1)。如果我理解正确,Scala将不得不继续使用匿名类在Java 8将使用lambda的上下文中实例化接口(因为Java 8 lambda的语义与Sc​​ala lambda的语义不同)。我还不清楚的另一点是,如果Java方法返回Java lambda,将会发生什么。如果Scala类调用该方法会怎样?Scala中的返回类型是什么?
Giorgio

1
@Giorgio在Java 8中,lambda表达式是一种语言级的快捷方式,用于创建声明一个方法并受上下文延迟的接口实例。因此,当Java 8方法返回lambda时,它实际上返回接口的实例,该实例被声明为该方法的返回类型。从Scala 2.9.1开始,返回类型将只是某个接口实例(Runnable或Comparator)的实例,您不能将其视为Scala lambda,除非您或以后的Scala libary版本引入了隐式转换Scala lambda类型的接口。
hellodanylo

@SkyDan:好的,因此Scala会将Java lambda视为实现某些接口的对象。这一点对我来说并不明确:我认为Java会生成一些与对象不同的字节码。但是它必须是一个底层的对象,否则它将不被视为接口的实现。我想我现在明白了。
Giorgio 2013年

@Giorgio,如果您想进一步了解Java 8中与lambda相关的更改以及推动这些更改的因素,我建议您阅读Lambda项目的这一有趣且详细的概述
hellodanylo

@SkyDan:现在阅读。在我看来,lambda 确实代表对象(即使类型/接口是从定义它们的上下文中推断出来的)。因此,在mail.openjdk.java.net/pipermail/lambda-dev/2011-August/…(“lambdas不是对象”)中给出的信息是不正确的,至少是具有误导性的。
Giorgio 2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.