Переопределение метода без расширения (java)

Я пытаюсь переопределить метод класса, который используется в API, без его расширения. Есть ли способ сделать это без перекомпиляции исходного кода? Я не могу расширить класс, потому что его экземпляр создается внутри другого класса, а также есть другие классы, которым необходимо его расширить.

Пример:

    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 и пытаюсь переопределить метод onAllChildrenAddedToPage() в DomNode. DomNode используется классом WebClient и должен быть преобразован в HtmlElement в какой-то момент внутри WebClient и DomNode. Я создал DomNode2 (который расширяет DomNode) после получения его экземпляра из WebClient, но он выдал исключение ClassCastException, потому что DomNode2 нельзя преобразовать в HtmlElement.


person user3335154    schedule 21.02.2014    source источник
comment
Я не понимаю, почему расширение DomNode и переопределение onAllChildrenAddedToPage() вызывает ClassCastException. Но, глядя на API htmlunit, HtmlElement расширяет DomNode. Таким образом, ваш DomNode2 может расширять HtmlElement и переопределять onAllChildrenAddedToPage(). Это решит вашу проблему ClassCastException, потому что кто-то пытается преобразовать ваш объект в HtmlElement.   -  person anonymous    schedule 21.02.2014
comment
Я только что попытался расширить HtmlParagraph (это не HtmlElement, который дал мне ошибку, мой плохой), и по какой-то причине он все еще выдавал ошибку ClassCastException. Я дал DomNode2 конструктор, назвал super и поместил их в один пакет. Это действительно странно. Исключение в потоке main java.lang.ClassCastException: com.gargoylesoftware.htmlunit.html.HtmlParagraph не может быть приведен к com.gargoylesoftware.htmlunit.html.DomNode2   -  person user3335154    schedule 21.02.2014
comment
Могу я спросить, чего вы пытаетесь достичь в более широкой картине? Возможно, также опубликуйте свой код.   -  person anonymous    schedule 21.02.2014


Ответы (1)


Нет простого способа сделать это без перекомпиляции исходного кода. Вы абсолютно уверены, что то, что вы пытаетесь сделать, необходимо? Если да, рассмотрите возможность перекомпиляции исходного кода с помощью собственного пользовательского метода, поскольку исходный код HtmlUnit является открытым.

Если вы действительно не хотите перекомпилировать, вы также можете попробовать отредактировать байт-код класса с помощью ASM. . Это довольно сложно, хотя и не очень хорошая практика.

Если вам нужно только добавить код в метод, вы можете использовать перехватчики методов для запуска кода при вызове метода. Проверьте этот вопрос о перехватчиках методов для получения дополнительной информации о том, как это сделать.

person kabb    schedule 21.02.2014
comment
Да, я должен переопределить метод, потому что то, что я хочу сделать, вызывается рекурсивно внутри DomNode, и рекурсия обратна тому, что я хочу (родительские узлы вызывают дочерние узлы, поэтому дочерние узлы обрабатываются первыми). ASM выглядит слишком сложным, я попробую перехватчики методов и отредактирую исходный код, если это не сработает. Спасибо. Хотя, если у кого-то есть другое решение, я хотел бы его услышать. :) - person user3335154; 21.02.2014