JDK升级后避免实现接口新增方法的解决方案咨询
刚好之前帮团队做Java 6到Java 8的JDBC升级时碰到过一模一样的问题,给你几个靠谱的解决方案,按推荐程度排序:
解决方案1:抽象适配器类(最推荐)
这是Java里处理接口新增方法最经典的手段,核心思路是用一个抽象中间类承接接口的所有新增方法,给它们提供默认实现,你的业务类只需要继承这个中间类,不用再直接实现Connection接口。这样既不用把业务类改成抽象类,也不用实现所有不想管的新增方法。
举个具体的代码示例:
// 抽象适配器类,专门处理Connection接口的新增方法 public abstract class AbstractConnectionAdapter implements Connection { // 实现Java 8新增的getSchema方法,根据需求返回默认值或抛出不支持异常 @Override public String getSchema() throws SQLException { // 如果你的业务不需要这个方法,可以抛出异常明确告知 throw new UnsupportedOperationException("getSchema() 暂不支持"); // 或者返回一个默认值,比如 return "public"; } @Override public int getNetworkTimeout() throws SQLException { // 返回默认超时时间,或者抛出异常 return 30000; // 30秒默认超时 } // 把所有Connection接口新增的、你不想实现的方法都在这里处理 // 注意:Java 6中你已经实现过的方法,不需要在这里定义,交给子类去实现 } // 你的业务类现在继承适配器类,而非直接实现Connection public class MyCustomConnection extends AbstractConnectionAdapter { // 只需要实现你原有业务逻辑需要的方法即可 @Override public Statement createStatement() throws SQLException { // 你的原有业务逻辑 return new MyCustomStatement(); } // 其他你在Java 6中已经实现的方法... }
这种方式的好处是代码清晰、维护成本低,后续如果接口再新增方法,只需要在适配器类里统一处理就行,不用修改业务类。
解决方案2:动态代理(适合临时/灵活场景)
如果不想写一堆适配器代码,或者需要动态处理不同的方法逻辑,可以用Java的动态代理机制。通过代理类拦截方法调用,只处理你关心的方法,其余方法直接抛出异常或返回默认值。
示例代码如下:
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.sql.Connection; import java.sql.SQLException; import java.sql.Statement; public class ConnectionProxyHandler implements InvocationHandler { // 如果你是包装一个现有Connection实例,可以保留这个引用 private final Connection delegateConnection; public ConnectionProxyHandler(Connection delegate) { this.delegateConnection = delegate; } // 生成代理实例的静态方法 public static Connection createProxy(Connection delegate) { return (Connection) Proxy.newProxyInstance( Connection.class.getClassLoader(), new Class[]{Connection.class}, new ConnectionProxyHandler(delegate) ); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String methodName = method.getName(); // 只处理你业务需要的方法,比如原来Java 6中实现的那些 if ("createStatement".equals(methodName) || "prepareStatement".equals(methodName)) { // 可以调用原有Connection的方法,或者执行自定义逻辑 return method.invoke(delegateConnection, args); } // 对于新增的、不需要的方法,直接抛出不支持异常 throw new UnsupportedOperationException("方法 " + methodName + " 暂不支持"); } }
使用的时候,只需要把你的原有Connection实例包装成代理对象即可:
Connection myConnection = ConnectionProxyHandler.createProxy(new MyOriginalConnection());
这种方式比较灵活,但代码相对复杂,适合临时过渡或者需要动态调整方法逻辑的场景。
补充说明
可能有人会想到用Java 8的默认方法,但这里行不通——因为Connection是JDBC的官方接口,我们无法修改它来添加默认实现,所以抽象适配器类是最稳妥、最易维护的方案。
内容的提问来源于stack exchange,提问作者SocketM




