Если вы не являетесь поставщиком JDBC, неразумно реализовывать подобные интерфейсы.
Попробуйте использовать прокси для обеспечения совместимости между версиями JVM.
Миграция на прокси выполняется следующим образом. Рассмотрим эту ResultSet
реализацию:
public class ResultSetFoo implements ResultSet {
public String getString(int columnIndex) throws SQLException {
return "foobar";
}
// other Java 1.4 methods
Это будет изменено, поэтому ни один класс не реализует ResultSet
:
public class ResultBar {
public String getString(int columnIndex) throws SQLException {
return "foobar";
}
// other method signatures matching the 1.4 ResultSet, as before
Затем вам нужно будет построить отображение методов между двумя типами во время выполнения (примитивная форма утки):
private static final Map RESULT_SET_DUCK = initResultSet();
private static Map initResultSet() {
Map map = new HashMap();
Method[] methods = ResultSet.class.getMethods();
for (int i = 0; i < methods.length; i++) {
try {
Method match =
ResultBar.class.getMethod(methods[i].getName(),
methods[i].getParameterTypes());
map.put(methods[i], match);
} catch (SecurityException e) {
throw new IllegalStateException(e);
} catch (NoSuchMethodException e) {
// OK; not supported in 1.4
}
}
return map;
}
Это позволяет вам вызывать тип ResultBar
через прокси:
/** Create a java.sql.ResultSet proxy */
public static ResultSet proxy(final ResultBar duck) {
class Handler implements InvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Method proxiedMethod = (Method) RESULT_SET_DUCK.get(method);
if (proxiedMethod == null) {
throw new UnsupportedOperationException("TODO: method detail");
} else {
return invoke(proxiedMethod, duck, args);
}
}
private Object invoke(Method m, Object target, Object[] args)
throws Throwable {
try {
return m.invoke(target, args);
} catch (InvocationTargetException e) {
throw e.getCause();
}
}
}
return (ResultSet) Proxy.newProxyInstance(null, RSET, new Handler());
}
Такие реализации должны позволять использовать код, скомпилированный в одной JVM, в будущих JVM, даже если будут добавлены новые методы. Существующие сигнатуры методов вряд ли изменятся, потому что одно дело заставить поставщиков баз данных сделать некоторую работу; что-то еще, что заставит всех пользователей API измениться.
Возможно, вам придется изменить способ создания экземпляров класса. Вы больше не можете использовать конструктор напрямую:
ResultSet nonPortable = new ResultSetFoo();
//becomes...
ResultSet portable = proxy(new ResultBar());
Если вы уже используете фабрику / строителя / и т. Д. Выкройка этого бита проста.
Хотя отражение в последних JVM относительно дешевое, в старых версиях оно меньше; это может отрицательно сказаться на производительности.