Экземпляр интерфейса без класса реализации - PullRequest
1 голос
/ 14 октября 2011

У меня есть шаблон JET, предназначенный для генерации кода для класса реализации интерфейса. У меня возникают проблемы с созданием исполняемого тестового класса, который печатает этот сгенерированный код, потому что я не могу получить объект для аргумента метода generate, созданного из шаблона JET.

Я хочу, чтобы тестовый класс работал примерно так:

/**
 * An executable test class that prints out exemplary generator output
 * and demonstrates that the JET template does what it should.
 */
public class TestClass {
    public static void main(String args[]) throws ClassNotFoundException, InstantiationException, IllegalAccessException {

        String className = "A"; // "A" is the name of the interface in the same package.

        Class c = Class.forName(className);
        Object o = c.newInstance();

        Q2Generator g = new Q2Generator(); // Class created from the JET Template
        String result = g.generate(o);
        System.out.println(result);
    }
}

Но, очевидно, c.newInstance(); не работает для интерфейса. Есть ли другой способ, которым я мог бы передать объект интерфейса методу generate? Мне нужен объект интерфейса, потому что в методе generate Q2Generator он получает информацию об объявлениях метода в интерфейсе из аргумента объекта.

Я не уверен, обеспечивает ли это достаточный контекст, но если этого недостаточно, есть еще детали в другом вопросе, который я задал здесь: Использование JET для генерации кода: отступ кода

Спасибо.

1 Ответ

3 голосов
/ 14 октября 2011

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

import java.lang.reflect.*;

public class ImplementInterfaceWithReflection {
    public static void main(String[] args) throws Exception {
        String interfaceName = Foo.class.getName();
        Object proxyInstance = implementInterface(interfaceName);
        Foo foo = (Foo) proxyInstance;
        System.out.println(foo.getAnInt());
        System.out.println(foo.getAString());
    }

    static Object implementInterface(String interfaceName)
            throws ClassNotFoundException {
        // Note that here we know nothing about the interface except its name
        Class clazz = Class.forName(interfaceName);
        return Proxy.newProxyInstance(
            clazz.getClassLoader(),
            new Class[]{clazz},
            new TrivialInvocationHandler());
    }

    static class TrivialInvocationHandler implements InvocationHandler {
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) {
            System.out.println("Method called: " + method);
            if (method.getReturnType() == Integer.TYPE) {
                return 42;
            } else {
                return "I'm a string";
            }
        }
    }

    interface Foo {
        int getAnInt();
        String getAString();
    }
}
...