Java中向后兼容的包装类
关于维护Java的向后兼容性,这里有一个interesting article。在包装类部分,我不能真正理解包装类完成了什么。在以下来自MyApp
的代码中,WrapNewClass.checkAvailable()
可以替换为Class.forName("NewClass")
static {
try {
WrapNewClass.checkAvailable();
mNewClassAvailable = true;
} catch (Throwable ex) {
mNewClassAvailable = false;
}
}
<>考虑^ {< CD4>}不可用时。在使用包装器的代码中(见下文),我们所做的只是将不存在的类替换为存在但无法编译的类,因为它使用的是不存在的类
public void diddle() {
if (mNewClassAvailable) {
WrapNewClass.setGlobalDiv(4);
WrapNewClass wnc = new WrapNewClass(40);
System.out.println("newer API is available - " + wnc.doStuff(10));
}else {
System.out.println("newer API not available");
}
}
有人能解释为什么这会有不同吗?我认为这与Java如何编译代码有关——我对此不太了解
# 1 楼答案
这一点是让代码针对一些类编译,而这些类在运行时可能不可用。WrapNewClass必须存在于javac的类路径中,否则无法编译。但是,在运行时的类路径中可能会缺少它
如果mNewClassAvailable为false,您引用的代码将避免引用WrapNewClass。因此,它将只打印“新API不可用”消息
然而,我不能说我印象深刻。总的来说,我见过用java来安排这种事情。而不是试图捕获异常。顺便说一句,即使在编译时,类也看不到任何地方
# 2 楼答案
我在spring和richfaces中见过这种行为。例如,Spring执行以下操作
private static
内部类,它在其中引用JSF类Class.forName(..)
一个JSF类请注意,内部类在被引用之前不会被加载,因此可以使用其中不满足的依赖项
(spring类是
org.springframework.web.context.request.RequestContextHolder
)# 3 楼答案
从JSE中的1.1开始,我就一直需要支持每一个JVM,并使用这些包装技术兼容地支持可选API——也就是说,API使应用程序工作得更好,但对它来说不是必需的
我使用的两种技术似乎(很差?)在您引用的文章中描述。与其对此作进一步评论,我将提供我如何做到这一点的真实例子
最简单的静态包装方法
需要:如果API可用,则调用它,否则什么也不做。这可以针对任何JVM版本进行编译
首先,设置一个静态
Method
,它具有反射的方法,如下所示:并包装反射的方法,而不是使用直接调用:
静态包装类
需要:如果API可用,则调用该API,或者以其他方式调用较旧的API以获得等效但降级的功能。这必须针对较新的JVM版本进行编译
首先设置一个静态包装器类;这可能是一个静态单例包装器,或者您可能需要包装每个实例创建。下面的示例使用静态单例:
并创建一个子类,以便在可用时提供更新的功能: