【问题标题】:How to find all implementations of a Java interface, without instantiating them all如何找到 Java 接口的所有实现,而不实例化它们
【发布时间】:2017-01-15 22:48:30
【问题描述】:

我为我的应用程序中的不同“数据点”创建了一组接口。我希望能够以相当模块化的方式添加或删除“数据点”,并且只加载用户需要的那些。目前我只有一个列表,我可以通过 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());
}

可以创建一个如下所示的 switch 语句:

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

虽然这在性能方面可能更好,但维护起来有点痛苦。

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

【问题讨论】:

  • 您可以在该 switch 语句中传入一个枚举,而不是使用 int。不易出错。

标签: java android interface


【解决方案1】:

如果您想要一个低维护的解决方案,您可以使用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);
    }

【讨论】:

  • 我对 Android 开发还很陌生,所以我不完全确定如何使用反射......
猜你喜欢
  • 1970-01-01
  • 2010-10-11
  • 2016-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-16
  • 1970-01-01
  • 2011-03-10
相关资源
最近更新 更多