2017-10-18 233 views
4

我需要编写代码来处理日期。我们正在慢慢地从Java 7过渡到Java 8,所以我的库代码必须同时使用。出于这个原因,它必须编译Java 7中在Java 7中编译使用Java 8类型的方法

然而,已经迁移到Java 8项目中使用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 
} 

我不是用在Java 8中引入lambda表达式或其他语言的东西我使用Java编译器8无论如何请看下面的语句。我想要的是创建Java 7兼容代码(因此没有UnsupportedClassVersionError),当Java 7中第三个if分支命中时(NoClassDefFoundError),该代码会中断。

目前上面的代码根本不编译,如果我使用Java 8 javac编译器设置为Java 7目标。

我在一个Java 8环境

<javac includeantruntime="false" srcdir="src" destdir="build/compiled" target="1.7" source="1.7" 

运行Ant但是,如果使用import java.time.LocalDateTime作为它不会编译。 我想到的是一个Java编译器8靶向Java 7的就没有那么聪明,看到虽然LocalDateTime是Java 8类路径,它不是在Java 7中

我不希望是什么使用反射(if (obj.getClass().getCanonicalName().equals("java.time.LocalDateTime")和其他基于反射的东西)和我宁愿不依赖性增加ThreeTen-Backport如JSR-310类型在Java中正在使用的7个项目,我更喜欢从Java排除threeten 8个项目而不弄乱常春藤依赖关系文件。

任何聪明的想法?我已经有一个解决方案(服务提供商界面与单独的罐子),但我想保持它作为最后的手段。

+1

检查旧软件(很容易)是否在java 8下运行,并首先执行运行时转换。其他任何东西都是混乱的。然后,您可以在闲暇之余迁移,并提供正确的反馈。 –

+0

有些客户直到2025年才会迁移到Java 8.这是我的约束条件 –

+0

鉴于编译器将始终包含对java.time的引用,因此尝试编写J7和J8兼容解决方案将不起作用。如果你现在不能迁移到J8,那么坚持jodatime(虽然J7从'11,J8从'14)。 –

回答

1

使你的代码Java7和Java8兼容的唯一可靠的方法是不使用任何特定Java8的功能,包括Java8和字节代码版本中引入的任何类。标准的工程实践是遵循最通用的原则,即Java7和Java7兼容的库。

导入技巧不会为您节省任何东西。 JVM迟早会加载类,然后你会得到一个例外或另一个例外。

使用反射会的工作,但你最终与可怕丑陋,无法读取代码,没有类型安全。最重要的是,让你的代码在不同的JVM版本上以不同的方式运行可能是一个很难调试的问题。

还有其他秘密的技巧,如操纵字节码或类加载,但这是如履薄冰,当你最不需要它有可能打破。

如果你绝对要使用不同版本并排侧,你可以将代码分成两个部分,并在不同的JVM上运行它。但是如果你只编写一个库,那么制作两个版本可能会更容易 - 一个用于Java7(也与Java8兼容),另一个用于Java8。

2

我认为你正在寻找一个错误的“水平”的解决方案。您希望避免代码重复,因此您正在寻找技术解决方案,我宁愿将其称为“元版本控制”问题。

因此,一个专门的无答案:考虑放弃拥有单个代码库的想法,该代码库服务于两个主人。相反:“分支”你的库的java7版本。另一方面,您的“主”分支完全支持java8。当然,java7版本只存在重要的错误修复,必须进入它 - 所有活动的开发发生在您的“主”java8分支上。然后使用技术为您提供支持 - 例如git cherry-pick之类的功能可以在您必须在两个分支中进行类似更新时减少工作量。

0

最好的事情:分支代码。主人将是Java 8版本。

不太推荐的方法:使用您的构建框架来决定日期处理程序。 你可以有2个子模块。子模块可以具有相同包中的类。并且该类的调用将是:

MyDateHandler.handle(); 

而您的构建文件决定根据java版本采取哪个类。 在maven中我们可以有配置文件。因此,在一个配置文件中,您可以使用MyDateHandler的Java 7实现进行构建。在Java 8中,您可以使用Java 8实现来构建。

+0

这实际上是我们目前正在做的事情:两个单独的工件中的两个模块 –

相关问题