我有一个PropertyBag
类,用于模拟对象可以使用的一组属性。
我还有几个类A1, A2, ..., AN
,它们具有
public A...(PropertyBag);
所有这些类都实现了接口 iA
。
我使用反射来创建A...
传递的相关PropertyBag
。我从PropertyBag
对象中提取数据以生成该类的候选成员数据。
我希望能够做的是在编译时强制类A...
的实现者来实现上述形式的构造函数。我知道我的要求很奇怪:你为什么要标准化施工参数?但我在这里有一个案例。
当然,我可以做的是有一个单独的构造和初始化步骤,因为我可以将初始化函数标记为抽象,甚至可能将iA
更改为包含该抽象初始化函数定义的抽象类。我会用反射来调用初始化。如果任何A...
缺少初始化函数,这将给我编译时失败。但我不喜欢将构造和初始化分离为构造但未初始化的对象没有意义的想法。
我在这里错过了一招吗? (在C ++中,我可以在编译时使用模板强制执行,但在Java中看不到方法)。
答案 0 :(得分:8)
我希望能够做的是在编译时强制类A的实现者...来实现上述形式的构造函数。
你不能,我害怕。 Java中没有任何内容可以强制执行。
你可以做的是写一个单元测试,它找到实现接口的所有类(例如,通过查找jar文件中的所有类),然后检查它们是否有这样的构造函数。它不如编译时安全性好,但它总比没有好。
答案 1 :(得分:1)
尽管乔恩说过,但还是有办法强制一个构造函数。
从界面iA创建一个抽象类。在这个抽象实现中,您可以定义所需的构造函数,并确保没有默认构造函数。
让所有类扩展抽象实现。他们将不得不实现一个构造函数并调用超级构造函数(这是你将初始化代码放在哪里)。
虽然有一个问题。实现的构造函数可以具有任何签名(默认签名除外)。
也许这个技巧可以帮助你。
答案 2 :(得分:1)
您可以通过为构造函数创建抽象来间接实现此目的:
public class ConstructionTest {
private interface Constructed { // iA in the question
// some methods
}
private static class PropertyBag {
}
private interface Constructor {
public Constructed construct(PropertyBag bag);
}
public class TestConstructor implements Constructor {
public Constructed construct(PropertyBag bag) {
return new Constructed() { };
}
}
@Test
public void testConstruct() {
Object potentialConstructor = new TestConstructor();
if (Constructor.class.isAssignableFrom(potentialConstructor.getClass())) {
Constructor constructor = (Constructor) potentialConstructor;
Constructed constructed = constructor.construct(new PropertyBag());
assertNotNull(constructed);
}
}
}
这会增加复杂性,更多类,更多接口,并且您可能需要Constructor
每iAN
个实现。