Проблема с анонимным внутренним классом в сгенерированном Javassist классе

Я использую Javassist для создания некоторых классов во время выполнения, и когда я создаю анонимные внутренние классы в этих классах, они падают при попытке создать экземпляр окружающего объекта (насколько я могу судить)

Я попытался реализовать простейшую версию того, что я пытаюсь сделать.

Я определяю 3 класса следующим образом:

public class A {

    public int method() {
        return 1;
    }
}

public class B extends A {

}

public class C extends A {
    public int method() {
        return 5;
    }
}

Что я хочу сделать сейчас, так это использовать javassist (или что-то еще, я думаю), чтобы (во время выполнения) создать класс, который имеет все функциональные возможности C, но расширяет B вместо A, мне это кажется вещью, которая была бы хорошо, так как B расширяет A. В настоящее время я делаю это следующим образом:

ClassPool cp = ClassPool.getDefault();
CtClass cc = cp.get(C.class.getName());

cc.setName("newName");
cc.setSuperclass(cp.get(B.class.getName()));

B b = (B) cc.toClass().newInstance();

b.method();

Приведенный выше код отлично работает, когда я вызываю метод(), но если я создаю экземпляр анонимного внутреннего класса в методе C() следующим образом:

public class C extends A {
    public int method() {
        try {
            return new Callable<Integer>() {

                @Override
                public Integer call() throws Exception {
                    return 5;
                }

            }.call();
        } catch (Exception e) {
            return 2;
        }
    }
}

когда я звоню method(), я получаю java.lang.NoSuchMethodError: C$1.<init>(LnewName;) ошибку.


person Carl Minden    schedule 31.01.2014    source источник
comment
Я не знаю JavaAssist, но похоже, что он не создает анонимный внутренний класс. Почему вам все равно нужно это делать? Это звучит как симптом неправильного дизайна наследования объектов.   -  person Tim B    schedule 31.01.2014
comment
Да, я делаю что-то довольно глупое, я понимаю, что, возможно, мне придется сделать это по-другому, но подумал, что могу спросить   -  person Carl Minden    schedule 31.01.2014


Ответы (2)


Хотя я бы хотел, чтобы кто-нибудь сказал мне по-другому, я думаю, что это может быть невозможно с Javassist, я нашел следующую строку в разделе 4.7 руководства по Javassist:

«Внутренние классы или анонимные классы не поддерживаются».

Поэтому я думаю, мне следует изучить другие библиотеки генерации классов времени выполнения.

person Carl Minden    schedule 31.01.2014
comment
Внутренние классы поддерживаются, но только статические - person Luca Basso Ricci; 31.01.2014
comment
И кто-нибудь знает, есть ли альтернатива работе с нестатическими внутренними классами? - person Francisco Javier Rojas; 08.03.2020

Javassist не поддерживает нестатические внутренние классы.
См. javadoc для метода CtClass.makeNestedClass(String nestedClassName,boolean isStatic).
Ваша проблема не может быть решена, если вы не перейдете на верхний уровень своего внутреннего класса anon.

person Luca Basso Ricci    schedule 31.01.2014
comment
Я попробовал API makenestedclass, он добавил класс в объект CtClass, но когда я преобразовал объект CtClass в объект класса, внутреннего класса там нет. Насколько я читал, будет проблема с преобразованием байтового кода внутреннего класса, см. этот github.com /jboss-javassist/javassist/issues/6 - person Sudarshan; 10.03.2015