【问题标题】:How to implement a parameterized interface at runtime?如何在运行时实现参数化接口?
【发布时间】:2012-12-23 06:40:30
【问题描述】:

我已经检查了 Java 代理和 cglib,但我还没有找到任何关于我将如何开始这个项目的示例。

这是我需要做的。

我有一个界面:

public interface RoadMap<T extends City>{
    public void map(T city);
}

我有一堆不同类型的城市作为名为@9​​87654322@的类的内部类

我希望能够在运行时通过循环遍历Cities 类的不同内部类来实现接口,如下所示:

for(Class clazz : Cities.class.getDeclaredClasses()){
   //implement RoadMap interface 
}

所有实现都是相同的,除了类型参数需要是 clazz 类型(在 for 循环中)。

这甚至可能吗?如果是这样,我应该从哪里开始。 Java Proxies 和 cglib 谈了很多关于方法拦截的事情,但这并不是我真正想要做的。

谢谢

【问题讨论】:

  • 您意识到.getDeclaredClasses() 得到内部类,而不是子类,对吧?
  • 是的,我想要内部类
  • 但你说“通过像这样循环遍历 Cities 类的不同子类:”
  • 对不起,我的错误。我最终通过使用 Javassist 并在运行时生成字节码来完成这项工作。

标签: java generics proxy cglib


【解决方案1】:

如果所有实现都相同,您只需要一个实现。这是一个不关心泛型类型的实现,不使用动态代理(但您可以使用动态代理做同样的事情):

public class RoadMapFactory {
    @SuppressWarnings("unchecked")
    public <T extends City> RoadMap<T> createWithRawTypes() {
        return new RoadMap() {
            @Override
            public void map(City city) {
                System.out.println("I mapped this city : " + city);

            }
        };
    }

    public static void main(String... args) {
        RoadMapFactory factory = new RoadMapFactory();
        RoadMap<SubCity1> map1 = factory.createWithRawTypes();
        map1.map(new SubCity1());
        RoadMap<SubCity2> map2 = factory.createWithRawTypes();
        map2.map(new SubCity2());
    }
}

【讨论】:

  • 应该是new RoadMap&lt;T&gt;()
  • 应该,但想法是表明您可以使用原始实例并将其作为参数化实例返回,因为这就是您使用动态代理所做的事情。
  • 我不明白。既然你在创建它,你不应该用正确的参数化来创建它吗?
  • 这并不重要,因为原始类型隐藏在类型安全的外观之下。关键是要表明,在运行时,只存在原始类型。泛型类型的类型安全由编译器确保。因此,基本上与上述功能相同的动态代理(即不关心实际的参数化类型)可以正常工作。有关类似示例,请参阅 Collections.emptyList()。你认为它每次都返回一个新的参数化对象,但实际上它每次都返回相同的原始类型空列表。
  • 这通常可以工作。但是我需要运行时的类型信息来序列化和反序列化这些对象。我需要能够说 ParameterizedType type = (ParameterizedType)Cities.City.class.getGenericInterfaces()[0];
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-13
  • 1970-01-01
相关资源
最近更新 更多