2014-02-21 2 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? 
     } 
    } 

^Решение этой проблемы все, что мне нужно

Если вы хотите взглянуть на конкретную проблему, я использую HtmlUnit API, и я пытаюсь переопределите метод onAllChildrenAddedToPage() в DomNode. DomNode используется классом WebClient и должен быть перенесен в HtmlElement в некоторый момент внутри WebClient и DomNode. Я делаю DomNode2 (который расширяет DomNode) после получения его экземпляра из WebClient, но он дал исключение ClassCastException, потому что DomNode2 не может быть передан в HtmlElement.

+0

Я не понимаю, почему расширение DomNode и переопределение onAllChildrenAddedToPage() вызывает ClassCastException. Но, глядя на API htmlunit, HtmlElement расширяет DomNode. Таким образом, ваш DomNode2 может расширить HtmlElement и переопределить onAllChildrenAddedToPage(). Это решит вашу проблему ClassCastException, потому что кто-то пытается передать ваш объект HtmlElement. – anonymous

+0

Я просто попробовал расширить HtmlParagraph (не был HtmlElement, который дал мне ошибку, мой плохой), и по какой-то причине он по-прежнему выдавал ошибку ClassCastException. Я дал DomNode2 конструктор, названный супер, и помещал их в один и тот же пакет. Это действительно странно. Исключение из потока "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

Смежные вопросы