在 Java 7 中编译一个使用 Java 8 种类型的方法
Compiling in Java 7 a method that uses Java 8 types
我需要编写代码来处理日期。我们正在慢慢地从 Java 7 过渡到 Java 8,所以我的库代码 必须与两者一起工作 。因此必须编译 Java 7.
但是,已经迁移到 Java8 的项目开始使用 JSR-310 类型。
考虑以下陈述
if (obj instanceof Date){
//Serialize using SimpleDateFormat
} else if (obj instanceof org.joda.time.LocalDateTime){
//Serialize using Joda
} else if (obj instanceof java.time.LocalDateTime){
//Serialize using JSR 310
}
我没有使用 Lambdas 或其他由 Java 8 引入的语言。无论如何,我正在使用 Java 8 编译器。我想要的是创建 Java 7 兼容代码(所以没有 UnsupportedClassVersionError
),当第三个分支在 Java 7 (NoClassDefFoundError
).[=20 中被击中时中断=]
目前,如果我使用为 Java 7 目标设置的 Java 8 javac 编译器,上述代码根本无法编译。
我运行蚂蚁在Java8环境
<javac includeantruntime="false" srcdir="src" destdir="build/compiled" target="1.7" source="1.7"
但是如果我使用 import java.time.LocalDateTime
作为 技巧 它不会编译。
我想象一个针对 Java 7 的 Java 8 编译器不是很聪明地看到 LocalDateTime
class 可用 在Java8class路径中,不在Java7.
中
我不想要的是使用反射(if (obj.getClass().getCanonicalName().equals("java.time.LocalDateTime")
和其他基于反射的东西)并且我不想添加对 ThreeTen-Backport 的依赖,因为 JSR-310 类型是 没有 在 Java 7 个项目中使用,我更愿意从 Java 8 个项目中排除 threeten 而不会弄乱 Ivy 依赖文件。
有什么好主意吗?我已经有了一个解决方案(带有单独 Jar 的服务提供商接口),但我想保留它作为最后的手段。
使您的代码与 Java7 和 Java8 兼容的唯一可靠方法是不使用任何 Java8 特定的功能,包括中引入的任何 classes Java8 和字节码版本。标准的工程实践是遵循最大公因数原则,即 Java7 和 Java7 兼容的库。
导入技巧不会为您节省任何东西。 JVM 迟早会加载 class,然后您将遇到一个或另一个异常。
使用反射会起作用,但最终会得到非常丑陋且不可读且没有类型安全性的代码。最重要的是,让你的代码在不同的 JVM 版本上 运行 不同,调试起来会很痛苦。
还有其他不为人知的技巧,例如操纵字节码或 class 加载,但这只是薄冰,可能会在您最不需要的时候打破。
如果您绝对必须并排使用不同的版本,您可以将代码分成两部分,然后 运行 在单独的 JVM 中。但是如果你只是在写一个库,那么制作两个版本可能更容易——一个用于 Java7(也与 Java8 兼容),另一个用于 Java8.
我觉得你找的解决方法就错了"level"。您想要避免代码重复,因此您正在寻找 技术 解决方案来解决我宁愿称为 "meta versioning" 问题的问题。
因此,一个专门的 none 答案:考虑放弃让单一代码库为 两个 主人服务的想法。相反:"branch off" 一个 java7 版本的库。另一方面,您的 "master" 分支完全支持 java8。当然,java7 版本只存在于重要的错误修复中,必须进入它 - 所有活跃的开发都发生在您的 "master" java8 分支上。然后使用技术来支持你 - 例如 git cherry-pick 之类的东西,当你必须在两个分支中进行类似的更新时,可以减少工作量。
最佳做法:分支代码。大师是Java 8版本。
不太推荐的方法:使用构建框架来决定日期处理程序。
你可以有 2 个子模块。子模块可以在同一个包中有一个 class。对 class 的调用将是:
MyDateHandler.handle();
并且您的构建文件根据 java 版本决定采用哪个 class。
在 Maven 中,我们可以有配置文件。因此,在一个配置文件中,您可以使用 Java 7 MyDateHandler 的实现来构建。在 Java 8 中,您可以使用 Java 8 实现进行构建。
我需要编写代码来处理日期。我们正在慢慢地从 Java 7 过渡到 Java 8,所以我的库代码 必须与两者一起工作 。因此必须编译 Java 7.
但是,已经迁移到 Java8 的项目开始使用 JSR-310 类型。
考虑以下陈述
if (obj instanceof Date){
//Serialize using SimpleDateFormat
} else if (obj instanceof org.joda.time.LocalDateTime){
//Serialize using Joda
} else if (obj instanceof java.time.LocalDateTime){
//Serialize using JSR 310
}
我没有使用 Lambdas 或其他由 Java 8 引入的语言。无论如何,我正在使用 Java 8 编译器。我想要的是创建 Java 7 兼容代码(所以没有 UnsupportedClassVersionError
),当第三个分支在 Java 7 (NoClassDefFoundError
).[=20 中被击中时中断=]
目前,如果我使用为 Java 7 目标设置的 Java 8 javac 编译器,上述代码根本无法编译。
我运行蚂蚁在Java8环境
<javac includeantruntime="false" srcdir="src" destdir="build/compiled" target="1.7" source="1.7"
但是如果我使用 import java.time.LocalDateTime
作为 技巧 它不会编译。
我想象一个针对 Java 7 的 Java 8 编译器不是很聪明地看到 LocalDateTime
class 可用 在Java8class路径中,不在Java7.
我不想要的是使用反射(if (obj.getClass().getCanonicalName().equals("java.time.LocalDateTime")
和其他基于反射的东西)并且我不想添加对 ThreeTen-Backport 的依赖,因为 JSR-310 类型是 没有 在 Java 7 个项目中使用,我更愿意从 Java 8 个项目中排除 threeten 而不会弄乱 Ivy 依赖文件。
有什么好主意吗?我已经有了一个解决方案(带有单独 Jar 的服务提供商接口),但我想保留它作为最后的手段。
使您的代码与 Java7 和 Java8 兼容的唯一可靠方法是不使用任何 Java8 特定的功能,包括中引入的任何 classes Java8 和字节码版本。标准的工程实践是遵循最大公因数原则,即 Java7 和 Java7 兼容的库。
导入技巧不会为您节省任何东西。 JVM 迟早会加载 class,然后您将遇到一个或另一个异常。
使用反射会起作用,但最终会得到非常丑陋且不可读且没有类型安全性的代码。最重要的是,让你的代码在不同的 JVM 版本上 运行 不同,调试起来会很痛苦。
还有其他不为人知的技巧,例如操纵字节码或 class 加载,但这只是薄冰,可能会在您最不需要的时候打破。
如果您绝对必须并排使用不同的版本,您可以将代码分成两部分,然后 运行 在单独的 JVM 中。但是如果你只是在写一个库,那么制作两个版本可能更容易——一个用于 Java7(也与 Java8 兼容),另一个用于 Java8.
我觉得你找的解决方法就错了"level"。您想要避免代码重复,因此您正在寻找 技术 解决方案来解决我宁愿称为 "meta versioning" 问题的问题。
因此,一个专门的 none 答案:考虑放弃让单一代码库为 两个 主人服务的想法。相反:"branch off" 一个 java7 版本的库。另一方面,您的 "master" 分支完全支持 java8。当然,java7 版本只存在于重要的错误修复中,必须进入它 - 所有活跃的开发都发生在您的 "master" java8 分支上。然后使用技术来支持你 - 例如 git cherry-pick 之类的东西,当你必须在两个分支中进行类似的更新时,可以减少工作量。
最佳做法:分支代码。大师是Java 8版本。
不太推荐的方法:使用构建框架来决定日期处理程序。 你可以有 2 个子模块。子模块可以在同一个包中有一个 class。对 class 的调用将是:
MyDateHandler.handle();
并且您的构建文件根据 java 版本决定采用哪个 class。 在 Maven 中,我们可以有配置文件。因此,在一个配置文件中,您可以使用 Java 7 MyDateHandler 的实现来构建。在 Java 8 中,您可以使用 Java 8 实现进行构建。