Java泛型-实例化通配符类型的方法

时间:2018-08-10 02:46:26

标签: java generics

我正在尝试构建一个库,以支持部署特定对象的自定义实现。

  • A类是用户将告诉他们如何配置事物的部署入口点
  • B类将是保存定制实现实例的对象
  • C类将是用户可以扩展以创建自己的自定义实现的抽象类
  • D类将是扩展C类的自定义实现(不是LIB的一部分)

当用户使用Class A进行设置时,我希望他们能够执行以下操作:

/* this code will not be part of the lib */
ClassA a = new ClassA()
a.setClassCImpl(ClassD.class)

现在,当实例化B类时,它需要知道使用自定义实现 D类

/* this code will be part of the lib */
Class<? extends ClassC> classCImpl;

ClassB() {
    classCImpl = new ??? // this needs to be an instance of Class D
}

会有很多B类实例。我宁愿不需要B类来保留A类实例,但我不确定如果不在A类中使用静态内容,这是否有可能。

2 个答案:

答案 0 :(得分:1)

这种模式是使用批注的好用例。一些框架实现了这种行为,但是您可以很容易地实现它。

如果可以允许用户扩展B注释,则真的很方便。

例如,这样声明您的注释:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)

public @interface MeaningfulName {
    public Class<? extends ClassC> value(); // you can define a default
}

现在,当用户扩展B时,他们可以添加此注释

@MeaningfulName(ClassD.class)
public class CustomB extends ClassB {
    // whatever your class does
}

然后,您可以在运行时使用getAnnotation()提取此内容,并设置一些缓存,以避免频繁查找。获得Class属性后,您可以使用所需的策略(单例,工厂,正反射等)来获取适当的实例。

如果您只想坚持一个B类,则可以使用@Targetother ElementTypes来指定用户可以使用它的各种位置组合,尽管提取注释的方式有所不同。

答案 1 :(得分:-1)

ClassA:

ClassA {
    static Class<? extends ClassC> impl = ClassD.class
}

ClassB:

ClassC classCImpl;

ClassB() {
    classCImpl = ClassA.impl.getDeclaredConstructor().newInstance();
}

我认为这会起作用。