如何实现Java 8接口,但在Java 6上运行?

如何实现Java 8接口,但在Java 6上运行?,java,java-8,Java,Java 8,正如您所问,我有一个库,我希望与Java6保持兼容。同时,如果它的关键抽象能够实现java.util.function.Supplier,那就太好了 我通过实现自己的Supplier副本来捏造事实,这样至少可以使用lambdas,但除了提供两个不同的jar文件(啊Scala,我多么想念您针对不同语言规范的多个版本)之外,有没有办法让我的密钥抽象向前兼容?我认为这是不可能的。在某种程度上,您需要进行一次飞跃,您的库不再适用于8之前的java。你现在可以用正反两方面来做;缺点是目前还没有多少程序员熟

正如您所问,我有一个库,我希望与Java6保持兼容。同时,如果它的关键抽象能够实现
java.util.function.Supplier
,那就太好了


我通过实现自己的Supplier副本来捏造事实,这样至少可以使用lambdas,但除了提供两个不同的jar文件(啊Scala,我多么想念您针对不同语言规范的多个版本)之外,有没有办法让我的密钥抽象向前兼容?

我认为这是不可能的。在某种程度上,您需要进行一次飞跃,您的库不再适用于8之前的java。你现在可以用正反两方面来做;缺点是目前还没有多少程序员熟悉java8

Java8中有一些新特性,如lambda、default方法、静态接口方法、新类型推理系统、Stream等新实用程序,这些特性将对api的设计产生重大影响;它们不适用于较旧的java;保持与旧java的兼容性是API设计者的一个手铐


现在开始使用Java8的好处是,您的API将更加现代,不再有旧java的包袱。这将在(不远的)将来得到回报。

我失败了-这对“java”不起作用。包

一个技巧是提供Java8中定义的Supplier接口,因此您将提供一个“Java.util.function.Supplier”

如果客户机不是Java8之前的版本,那么这可以保证实现中的依赖性

当客户机在Java8上时,JREJAR优先于类路径,将使用“真实”实现

如果它不仅仅是一个接口,您可以在其中存根,那么如果占位符类被使用,我会试图让它抛出一个错误

不过,您需要在Java8JRE之前的版本上测试包的密封性。我认为情况并非如此

我在一些大型项目中看到过这种方法是偶然发生的,在这些项目中,jar被添加到JRE中之前包含了“java.”或“javax.”包(例如JSR jars)。这些在功能成为JRE的一部分之后很长一段时间都运行得很好

更新:

如下所述,类加载器在非JRE“java.*”包上运行,因此我一定是记错了遗留碎片(除非规则在1.3/1.4之前没有得到加强?)


也许使用“java.lang.reflect.Proxy”进行一些混乱的工作可能会取得成果,但这几乎不是一个透明的解决方案。

我认为除了提供2个版本的库之外,没有其他方法

我看到你在用maven。您可以使用依赖关系管理,有3个项目,如下所示:

  • fakir common:(在Java 6中)
  • fakir-java8:(在java8中,取决于fakir-common)
  • fakir-java6:(在java6中,取决于fakir-common)
在fakir公共部分中充分利用不需要使用供应商接口的代码

然后在其他两部分中实施供应商特定方面

您可以将该项目用作fakir-java6的依赖项:

streamsupport是Java 8 Java.util.function(函数)的一个后端口 接口)和java.util.stream(streams)API,用于java 6或 七,

多亏了它,两个fakir javaN项目将拥有几乎相同的代码。
甚至可以使用代码生成只编写一次。

因为
java.util.function
只包含功能接口,您可以使用它的“后端口”。当然,backport不能提供默认函数,只能定义接口,但这些接口是添加与Java8兼容性所需的全部

是一个后端口,它添加的不仅仅是接口,但它避免了名称冲突,并且不需要您执行两个单独的版本

要使用此方法,如果使用streamsupport,只需编写

import java8.util.function.*;
而不是

import java.util.function.*;

编辑:需要使用
-Xclassbootpath
,因为它定义了
java.util.function
,而不是使用不同名称的同一个东西,所以streamsupport是更好的选择。

您需要类似于retrolambda的东西。正如我所读到的,我在java 6上的客户端需要retrolambda,不是我?即使您没有实现
Supplier
,使用方法引用(例如
Supplier sup=faker::get)将类的实例用作
Supplier
,也很容易。这是一个很好的观点,费边。问题是,我也想在一个地方接受一个供应商,尽管我认为同样的技巧也会起到相反的作用。仔细看看未来Java 9版本的变化也可能有助于决定何时“关闭”旧的Java版本。就我个人而言,我会等到Java 9,因为模块概念会带来一些更大的变化。@mschenk74-好吧,Java 8有很多东西需要消化,所以最好早点开始。不过,我认为java9不会对API设计产生太大影响。因为java9可能会破坏许多使用内部API的旧代码,这些API将不再可访问,所以我打赌会有一些变化。这取决于所提供的库的类型:如果它是一个稳定、完整的长期库,那么等到没有其他方法时再使用可能是有意义的,但是如果它是一个动态库,必须对当前的想法和问题做出反应,那么最好尽快切换到java 8。实际上,java 6的API很好,只是如果可能的话,我希望通过实际接口实现前向兼容。@DuncanMcGregor-定义自己的功能接口很好。但使用与JDK(未来或当前)相同的名称是不好的。这对用户来说很烦人,因为很容易导入错误的一个,然后很难理解为什么它不能编译