标准化Java构造函数,以便通过反射使用

3

我有一个PropertyBag类,模拟对象可以使用的属性集合。

我还有几个类A1,A2,...,AN,它们具有以下形式的构造函数:

public A...(PropertyBag);

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

我使用反射来创建相关的A...对象,并传入一个PropertyBag。我从PropertyBag对象中提取数据,以获取类的候选成员数据。

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

当然,我可以将构造和初始化步骤分开,因为我可以将初始化函数标记为抽象的,甚至可以改变iA为包含该抽象初始化函数定义的抽象类。我将使用反射调用初始化函数。如果任何A...遗漏了该初始化函数,那么这将给我所需的编译时故障。但是,我不喜欢将构造和初始化分开,因为已构造但未初始化的对象没有意义。

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

3个回答

8
我希望能够做到的是,在编译时强制要求类A的实现者实现上述形式的构造函数。很遗憾,你无法做到这一点,Java中没有相应的规定。不过,你可以编写一个单元测试来查找所有实现该接口的类(例如通过在jar文件中查找所有类),然后检查它们是否具有此类构造函数。虽然不如编译时安全性好,但总比什么都不做要好。

1

尽管Jon说不行,但是有一种方法可以强制使用构造函数。

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

使所有类都扩展抽象实现。它们将被迫实现a构造函数并调用超级构造函数(这是您放置初始化代码的位置)。

不过有一个注意点。实现的构造函数可以具有任何签名(除了默认构造函数)。

也许这个技巧能帮到您。


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);
        }
   }
}

这会增加一点复杂度,需要更多的类和接口,你可能需要为每个 iAN 实现一个构造函数。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接