创建匿名动态运行时实例

时间:2012-07-31 11:45:57

标签: java

如何在运行时在java中动态创建接口的实现?

我有一个工厂,它将读取类Foo上的注释并创建类Bar的实例。为了使这个工厂是类型安全的,我希望我的客户工厂是一个工厂方法的接口,它接受类型Foo并返回类型Bar。然后我希望我的工厂在运行时实现这个工厂方法。

所有这一切都是因为工厂代码是多余的并且难以维护。如果在运行时生成,它将始终是最新的。

示例:

public class Foo{
    private String name;

    public String getName(){
        return name;
    }

    public void setName(String name){
        this.name = name;
    }
}

public class Bar{
    private String personName;

    public String getPersonName(){
        return personName;
    }

    public void setPersonName(String personName){
        this.personName= personName;
    }
}

public interface BarFactory{
    Bar create(Foo foo);
}

有办法做到这一点吗?

3 个答案:

答案 0 :(得分:1)

如果你只是想创建一个实现所需接口的实例 - 你可以简单地做这样的事情:

public <T> T newInstance (Class<T> type) {
    try {
        return type.newInstance();
    } catch (Exception ex) {
        try {
            // Try a private constructor.
            Constructor<T> constructor = type.getDeclaredConstructor();
            constructor.setAccessible(true);
            return constructor.newInstance();
        } catch (SecurityException ignored) {
        } catch (NoSuchMethodException ignored) {
            if (type.isMemberClass() && !Modifier.isStatic(type.getModifiers()))
                throw new SerializationException("Class cannot be created (non-static member class): " + type.getName(), ex);
            else
                throw new SerializationException("Class cannot be created (missing no-arg constructor): " + type.getName(), ex);
        } catch (Exception privateConstructorException) {
            ex = privateConstructorException;
        }
        throw new SerializationException("Error constructing instance of class: " + type.getName(), ex);
    }
}

如果您需要创建完全动态的inteface实现,那么您需要使用代理http://www.javaworld.com/javaworld/jw-11-2000/jw-1110-proxy.html

这是你要找的东西吗?

答案 1 :(得分:1)

使用Java代理反射。请参阅此处的示例:http://docs.oracle.com/javase/7/docs/api/java/lang/reflect/Proxy.html

答案 2 :(得分:0)

通常,由于Java不是动态语言,因此动态创建代码不是受支持的语言功能。但是,有不同的字节码生成器可以帮助您。也许先来看看Janino这是一个小的java内存编译器,它将在运行时从代码块创建可执行的字节码。不知道这是否能解决您的问题,因为我不完全理解这些要求。