我正在尝试执行以下代码:
public class Connector {
public static Connection getConnection() {
conn = DriverManager.getConnection(String, String, String);
conn.getClass().getMethod("close").setAccessible(false); // this is what i am trying to achieve
}
public static void close(Connection c) {
c.getClass().getMethod("close").setAccessible(true);
try{ c.close(); }
catch(Throwable e) {}
}
}
我想阻止其他人调用conn.close()
并强制用户使用Connector.close()
,因为有时conn.close()
会在调用时抛出NullPointerException
。它甚至可能吗?
答案 0 :(得分:2)
从理论上讲,使用"类加载器魔法"可能是这样的。
换句话说:你可以创建自己的类加载器,在加载时操纵特定的类。
使用问题中提出的反射很可能无法正常工作。请记住:反射主要是关于代码结构的反映。是的,在Java 9之前,您可以轻松转向"低级别"并更改字段的可访问性(除非有安全管理器),但除此之外,不允许更改代码结构。它适用于检查,而非操作。
所以,真正的答案是:不这样做。而是想一想人们应该使用的适当,干净的界面。
将某些东西公之于众,没有必要在运行时将其减少到更低。这与#34;正确的OOP"相反。
答案 1 :(得分:1)
不要编写自己的类加载器, 那很可怕。
而是创建自己的类,
或许命名为RestrictedConnection
并使用合成来包含真实的Connection
。
接下来,不要为RestrictedConnection类提供close
方法。
答案 2 :(得分:0)
您可以创建一个仅包含Connection对象的包装器对象,并将每个cllas重新路由到基础Connection,并关闭。
public class CustomConnection {
private Connection conn;
public CustomConnection( Connection conn ) {
this.conn = conn;
}
public void close() {
throw new ForbiddenException();
}
public void commit() {
this.conn.commit();
}
....
}
并更改您的Connector类:
public class Connector {
public static CustomConnection getConnection() {
conn = DriverManager.getConnection(String, String, String);
return new CustomConnection( conn );
}
}
答案 3 :(得分:0)
我想阻止其他人调用
conn.close()
并强制人们使用Connector.close()
,因为从jsp调用时有时会conn.close()
抛出NullPointerException
。它甚至可能吗?
即使 可能,它也无法满足您的目的。您只需更改JSP代码尝试调用Connection.close()
时发生的异常,很可能更改为IncompatibleClassChangeError
。那不是更好。
撇开一个问题,即你的JSP是否一开始就可以直接访问Connection
,或者调用它的close()
方法,你有时会得到一个NPE标志着应用程序逻辑中的缺陷。您应该追踪并修复它 - 为什么您的JSP有时会获得null
而不是真正的 Connection
- 而不是试图在症状上添加乐队助手
答案 4 :(得分:0)
我认为你最好的选择是:
子类连接,如果有人调用close,则抛出异常。这是一个更简单的选项,不会给出编译时错误,但调用它将永远不会工作,并且人们不会这样做(而不是因为它工作一次然后再得到错误)。
创建注释预处理器,以便在用户代码中调用方法时出现编译时错误。这更加困难和复杂,可能不是最好的方法,但会在编译时出错,这总是更好。
如果可能的话,使用Reflection最多会产生一个运行时错误,所以在这种情况下,我选择一个更简单,更清晰的选项。
答案 5 :(得分:0)
无法相信没有人提到这一点:弃用它,在以后的版本中将其删除
将public
转换为方法private
会导致代码破坏。
处理这种情况的最佳方法:通知其他人“将来可能会将其删除”:让他们有时间在破坏旧版本之前更新代码。
这是@Deprecated
的用途。如果其他人依赖他们的代码,请不要在没有警告的情况下破坏它稍后,您可以删除它,并保证您告知依赖项它将不再可访问。
是的,用户仍然可以使用它。但至少他们知道他们不应该使用它。这样做的好处是让依赖代码时间的开发人员能够更新他们的软件,而不是立即破坏他们的软件。