我正在尝试创建一个类来实现Java库中的接口。ResultSet应该是特定的,尽管特定的接口不应该与问题相关。(我需要在提供一些额外功能的常规ResultSet之上添加一个层,但我希望传递“常规”函数,我有几个函数应该能够接受常规的ResultSet或“增强的”ResultSet。)
我的问题是:我是否可以这样做,以便该类能够在Java 5和Java 6中成功编译?
Java6中的ResultSet接口中声明了许多函数,它们返回Java5中没有定义的对象。如果我包含这些函数,我的类将不会在Java5中编译,因为我引用的是未定义的类型。但是如果我不包括这些函数,那么我的类就不会在Java 6中编译,因为我没有完全实现接口。我好像被困在什么事上了-22。实际上,我不需要任何这些函数--事实上,我的实现只是抛出一个“未实现”的异常。
我们的一些程序员正在运行Java 5,有些正在运行Java 6。我们的生产环境是Java 5。我想,在一个更加完美的世界中,我们都会运行相同的版本。但是,即使我可以修改我们的环境,使问题在这种情况下没有意义,这个问题肯定会产生开源项目。如果我确实修改了我的代码以使用Java 5,那么当我们迟早升级到Java 6时,类就会中断,这看起来很烦人。
更新
谢谢你给出的答案。我很希望有人告诉我,“哦,如果你在这里加上这个注解或者输入字母'W‘,它都会神奇地工作。”我猜没有这样的运气。
所有收到的答案(无论如何,在这次更新的时候)都是好的,所以我对所有的答案都投了反对票,我给了最能表达我的意见的人“最佳答案”奖。:-)
我认为我真正的解决方案是放弃实现ResultSet的想法,而是创建一个新的接口,其中只包含来自ResultSet的函数,这些函数必须实现才能运行。我觉得这在情感上令人不满意,但似乎比其他选择要好。
发布于 2010-12-27 19:33:04
我想代理建议是最好的答案,但让我补充两个注意事项:
首先,通过向接口添加方法来更改公共API,依赖于以前版本中不存在的类的方法通常是令人厌恶的(与您一样,实现该接口的开发人员不可避免地会带来麻烦)。这种令人憎恶的现象很少见,第二种考虑可以减轻这种情况:
当然,JDBC是一个公共API。但不是很公开。我的意思是,它的接口通常只能由JDBC驱动程序提供程序实现。在这种情况下,对于不同的JDBC版本( 见如 )有不同的实现负担是可以忍受的。我的目标是阻止您实现一个实现/包装ResultSet的类,除了非常具体(低级别)的situations.In一般情况--将ResultSet传递给业务层是错误的做法;在典型情况下,JDBC驱动程序实例化ResultSet,DAO方法使用它,但从不返回它。
发布于 2010-12-27 18:34:59
我认为您应该使用代理类将服务实现为JDK代理。
它从1.3开始就已经出现了,所以它将在所有版本中工作。
语法是:
ResultSet rs = Proxy.newProxyInstance(
ResultSet.class.getClassloader(),
new Class[]{ResultSet.class},
new ResultSetInvocationHandler()
);ResultSetInvocationHandler将是InvocationHandler的一个实现,它用自定义逻辑拦截一些方法,并传递其他方法。
这是一个古老的关于代理机制的教程。
发布于 2010-12-27 19:05:47
啊,是的,伟大的JDBC向后兼容性崩溃了。你有权释放两品脱的固体咒骂朝太阳的方向为这一个。
我不认为您有任何方法可以对5和6使用完全相同的实现类。但是,您是否可以这样做:
abstract class JaysBaseSuperResultSet /* does not implement ResultSet */ {
// all needed methods for java 5
}
class JaysSuperResultSetForJava6 extends JaysBaseSuperResultSet implements ResultSet {
// all additional java 6 methods
}
class JaysSuperResultSetForJava5 extends JaysBaseSuperResultSetForJava5 implements ResultSet {
// class body can be empty; compile this only with java 5
}您需要有一个稍微奇怪的构建过程:我认为最简单的方法是用6编译器编译除JaysSuperResultSetForJava5之外的所有类,但是用-target 5编译,然后单独用5编译器编译该类,或者用6编译器编译,但连接到5个库(这可以完成,而且可能更简单)。
然后,您将需要一个工厂类,它检测当前版本并创建适当具体类的实例。
然后,您可以将所有东西打包到一个罐子中。
听起来会起作用吗?
编辑:意识到你可以用三个类,而不是四个类来完成这个任务。
https://stackoverflow.com/questions/4540898
复制相似问题