2014-02-21 52 views
0

我试图覆盖API中使用的一个类的方法而不扩展它。有没有办法做到这一点,而不重新编译源代码?我无法扩展该类,因为它的实例是在另一个类中创建的,还有其他类需要扩展它。覆盖一个没有扩展的方法(java)

例子:

import A,B,C; 

    public class Tester{ 
    public static void main(String[] args){ 

    A a = new A(); 
    a.getB().method(); 
    //The object I want to handle is A 
    //A has-a B and C 
    //C extends B and is used at some point inside B 
    //how can I override method() in B? 
     } 
    } 

^解决这个问题是我需要的

如果你想看看具体的问题,我使用的API的HtmlUnit,我想重写DomNode中的onAllChildrenAddedToPage()方法。 DomNode由WebClient类使用,需要在WebClient和DomNode内部的某个位置投射到HtmlElement中。从WebClient获取实例后,我创建了一个DomNode2(它扩展了DomNode),但它给出了一个ClassCastException,因为DomNode2不能转换为HtmlElement。

+0

我不明白为什么扩展DomNode和覆盖onAllChildrenAddedToPage()导致ClassCastException。但是看看htmlunit API,HtmlElement扩展了DomNode。所以你的DomNode2可以扩展HtmlElement并覆盖onAllChildrenAddedToPage()。这将解决您的ClassCastException问题,因为有人试图将您的对象转换为HtmlElement。 – anonymous

+0

我只是试图扩展HtmlParagraph(不是HtmlElement,给了我错误,我的坏),它仍然给出了ClassCastException错误出于某种原因。我给了DomNode2一个构造函数,叫做super,并将它们放在同一个包中。这真的很奇怪。 线程“main”中的异常java.lang.ClassCastException:com.gargoylesoftware.htmlunit.html.HtmlParagraph不能转换为com.gargoylesoftware.htmlunit.html.DomNode2 – user3335154

+0

请问您想在更大的图片中实现什么功能?也许还会发布一些你的代码。 – anonymous

回答

0

有没有简单的方法来做到这一点,而无需重新编译源代码。你确定你想要做什么是必要的吗?如果是,请考虑使用自定义方法重新编译源代码,因为HtmlUnit是开源的。

如果你真的不想重新编译,你也可以尝试使用ASM编辑类的字节码。这虽然相当困难,并不是一个很好的做法。

如果您只需要向该方法添加代码,则可以使用方法拦截器在该方法被调用时运行代码。查看this question on method interceptors了解更多关于如何做到这一点的信息。

+0

是的,我必须重写该方法,因为我想要做的是在DomNode内部递归调用,并且递归与我想要的相反(父节点调用子节点以便首先处理子节点)。 ASM看起来太难了,我会尝试方法拦截器并编辑源代码,如果这不起作用。谢谢。虽然如果其他人有其他解决方案,我想听听。 :) – user3335154