3

我有一个PropertyBag类,它为对象可消耗的一组属性建模。

我还有几个A1, A2, ..., AN具有以下构造函数的类

public A...(PropertyBag);

所有这些类都实现了接口 iA

我使用反射来创建相关的A...传递PropertyBag。我从对象中提取数据PropertyBag以产生类的候选成员数据。

我想要做的是A...编译时强制类的实现者实现上述形式的构造函数。我知道我的要求很奇怪:为什么要标准化构造参数?但我在这里有一个案例。

当然,我可以做的是有一个单独的构造和初始化步骤,因为我可以将初始化函数标记为抽象,甚至可以更改iA为包含该抽象初始化函数定义的抽象类。我会使用反射来调用初始化。A...如果缺少该初始化函数,那将给我我希望的编译时失败。但是我不喜欢将构造和初始化分开的想法,因为构造但未初始化的对象没有意义。

我在这里错过了一个技巧吗?(在 C++ 中,我可以在编译时使用模板强制执行,但在 Java 中看不到方法)。

4

3 回答 3

8

我希望能够做的是在编译时强制类 A... 的实现者实现上述形式的构造函数。

你不能,我害怕。Java中没有任何东西可以强制执行。

可以做的是编写一个单元测试来查找实现接口的所有类(例如,通过查找 jar 文件中的所有类),然后检查它们是否具有这样的构造函数。它不如编译时安全,但总比没有好。

于 2013-06-27T09:16:38.867 回答
1

尽管 Jon 说了什么,有一种方法可以强制构造函数。

从接口 iA 创建一个抽象类。在这个抽象实现中,您定义了您想要的构造函数,并确保没有默认构造函数。

让所有类扩展抽象实现。他们将不得不实现一个构造函数并调用超级构造函数(这是您放置初始化代码的地方)。

不过有一个问题。实现的构造函数可以有任何签名(默认的除外)。

也许这个技巧可以帮助你。

于 2013-08-21T08:22:45.500 回答
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.

于 2013-08-21T08:28:20.223 回答