在Java接口中重新定义wait方法
我想在一个流畅的API(用于
http://www.jooq.org)中使用wait(int)作为方法的签名.目标是能够像这个例子一样构造SQL查询:
SELECT * FROM T_AUTHOR WHERE ROWNUM <= 1 FOR UPDATE OF FIRST_NAME,LAST_NAME WAIT 5 完整的FOR UPDATE子句语法规范(至少对于Oracle)可以在这里看到: FOR UPDATE [ OF [ [ schema. ] { table | view } . ] column [,[ [ schema. ] { table | view } . ] column]...] [ { NOWAIT | WAIT integer | SKIP LOCKED } ] http://download.oracle.com/docs/cd/B28359_01/server.111/b28286/img_text/for_update_clause.htm 使用jOOQ,我真的希望接近SQL语法.所以我希望能够使用jOOQ流畅的API对上面的SQL子句进行建模,如下所示: Result<Record> result = create.select() .from(T_AUTHOR) .limit(1) .forUpdate() .of(FIRST_NAME,LAST_NAME) .wait(5) // Here's the issue .fetch(); fetch方法用于将API的底层对象呈现为SQL,并针对Oracle(或任何其他)数据库运行SQL语句.以上内容可以在界面中合法指定: /** * A type that models a "step" in the creation of a query using the fluent API */ public interface SelectForUpdateWaitStep extends SelectFinalStep { // [...] /** * Add a "FOR UPDATE .. WAIT n" clause to the query */ SelectFinalStep wait(int seconds); // [...] } 不过,我对此有一些疑问,因为存在与另一种方法发生冲突的风险: public class Object { // [...] public final native void wait(long timeout) throws InterruptedException; // [...] } 多亏了方法重载(int与长参数),我实际上可以做到这一点.但我担心它可能会让我的用户感到困惑并导致错误.所以这是错的: .forUpdate() .of(FIRST_NAME,LAST_NAME) .wait((long) 5) // This doesn't make sense .fetch(); // This doesn't compile 所以我的问题是: >我可以以某种方式阻止调用/访问Object.wait(long)altoghether?我不这么认为,因为它被宣布为最终,但也许有人知道编译器技巧,或其他什么? 解决方法
这需要一种禁用Object方法的方法.主要原因似乎是因为它有一个很好的名称,适合专有API的目的.
起初,这与继承的整个概念相矛盾 – 一旦从类继承,所有子类必须暴露相同的非私有字段&方法.您始终可以覆盖方法,除非(1)它被标记为final,(2)它具有不兼容(非协变)返回类型,这两种方法都适用于void wait(long)方法. 此外,由于每个对象都是Java中的Object,所以一切都必须有一个方法void wait(long),并且无法隐藏/删除/禁用/转发/覆盖它.假设有可能隐藏void wait(long)方法,如果你想调用它,你将如何调用它? 但是,假设您永远不需要为特定类调用void wait(long),那么AspectJ总是采用源/字节代码编织的方法,以便根据某些调用规则更改.class Java字节码.您可以捕获每个等待(长)的调用并声明错误/警告.在这里查看更多:http://www.eclipse.org/aspectj/doc/released/adk15notebook/annotations-decp.html 但是,即使使用带字节码编织的AspectJ,也无法使用本机方法切入点.最有可能的是,即使使用源代码编织也无法做到这一点 – 但它可能值得一试. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |