如何查找Java接口的所有实现,而无需全部实例化它们

时间:2017-01-15 22:48:30

标签: java android interface

我在我的应用中为不同的“数据点”创建了一组接口。我希望能够以相当模块化的方式添加或删除“数据点”,并且只加载用户需要的那些。目前我只有一个列表中的所有这些,我通过ID访问我需要的列表。当我添加DataPointMethods接口的实现时,我想用自我更新的东西替换它,并且这不需要我实例化我的所有类,无论我是否需要它们。现在这不是一个大问题,但考虑到可扩展性,我知道它会是。

当前代码:

private void setupMethodsList() {
    dataPointMethodsList = new ArrayList<DataPointMethods>();

    dataPointMethodsList.add(WorkoutMethods.getInstance());
    dataPointMethodsList.add(SleepMethods.getInstance());
    dataPointMethodsList.add(WalkingMethods.getInstance());
    dataPointMethodsList.add(FoodMethods.getInstance());
    dataPointMethodsList.add(WeightMethods.getInstance());
    dataPointMethodsList.add(WaterMethods.getInstance());
}

可以制作一个如下所示的开关语句:

public DataPointMethods getDataPointMethod(int dataPointID){

    DataPointMethods dataPointMethods;

    switch (dataPointID) {
        case 0:
            dataPointMethods = FoodMethods.getInstance();
            break;
        case 1:
            dataPointMethods = WorkoutMethods.getInstance();
            break;
         // TODO: add more cases each time I add a DataPoint...
        default:
            dataPointMethods = WorkoutMethods.getInstance();
            Log.w(TAG, "invalid DataPointID passed");
            break;
        // How do I just make the method just stop if the ID is wrong though? If default runs it is 100% definitely an error...
    }

    return dataPointMethods;
}

虽然这可能是更好的表现,但维持起来却很痛苦。

有没有更理想的解决方案?到目前为止,我发现的唯一解决方案涉及实例化一切,这违背了目的......

1 个答案:

答案 0 :(得分:0)

如果您需要低维护解决方案,可以使用ClassPathScanningCandidateComponentProvider扫描类路径以获取实现接口的类的名称。然后你可以使用反射从那里开始。

    ClassPathScanningCandidateComponentProvider scanner =
            new ClassPathScanningCandidateComponentProvider(false);

    scanner.addIncludeFilter(new AssignableTypeFilter(DataPointMethods.class));

    for (BeanDefinition bd : scanner.findCandidateComponents("basepackage")) {
        Class<?> clazz = Class.forName(bd.getBeanClassName());
        DataPointMethodsmethod = (DataPointMethods)clazz.getMethod("getInstance").invoke(null);
    }