编写使用类的两个实现之一编译的Java代码

Dem*_*emi 6 java ffi binary-compatibility source-compatibility

我正在用Java编写一些FFI代码,这些代码大量使用sun.misc.Unsafe.

在Java 9中,这个类将变得不可访问,并且将成为jdk.unsupported.Unsafe.我想编写我的代码,以便它现在可以工作,但继续在Java 9中工作.

最黑客的方法是什么?我更喜欢二进制兼容性,但源兼容性也没关系.

编辑:每次Unsafe调用方法时,我100%不能使用反射 - 甚至是虚拟调度.大多数这些方法都编译为单个机器指令.因此,性能真的很重要.拥有包装器是可以的 - 但只有当我确定JIT每次都会内联它们时才会这样.

我目前的计划是在运行时加载适当的类.

Dan*_*den 2

一种选择:您可以为需要访问的 Unsafe 上的方法提供一个小型垫片帮助器接口,有两种实现:一种用于sun.misc.Unsafe新的jdk.unsupported.Unsafe. 这两个类都可以作为二进制资源存储在 JAR 中,并且在类初始化期间(即在块中static),您可以创建一个新的 ClassLoader 并加载 shim 类。这会在类初始化期间给您带来一些反射开销,但在运行时不涉及反射,只涉及虚拟方法分派——只要您只加载一个实现类,JIT 就应该能够内联该虚拟方法。

如果您可以引入库依赖项,cglib 的 FastClass 基本上会为您轻松完成此操作。

与往常一样,对于此类低级性能黑客,您需要一些数据。为此创建一个 JMH 测试工具,并验证反射开销确实无法容忍的,并且 JIT 确实可以内联您的解决方案——这是确定的唯一方法。