我正在尝试构建一个库,以支持部署特定对象的自定义实现。
当用户使用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类中使用静态内容,这是否有可能。
答案 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类,则可以使用@Target
和other ElementTypes来指定用户可以使用它的各种位置组合,尽管提取注释的方式有所不同。
答案 1 :(得分:-1)
ClassA:
ClassA {
static Class<? extends ClassC> impl = ClassD.class
}
ClassB:
ClassC classCImpl;
ClassB() {
classCImpl = ClassA.impl.getDeclaredConstructor().newInstance();
}
我认为这会起作用。