如何通过实现名称从接口实现列表中获取元素

How to get element from a list of interface implementations by implementation name

我有一个 SomeInterface

的实现列表
List<SomeInterface> listOfThingsThatImplementsSomeInterface

我想根据其class名称从列表中提取具体实现

private SomeInterface getThisType(SomeInterfaceImpl myType) {
    SomeInterfaceImpl impl = null
    for (SomeInterface current: listOfThingsThatImplementsSomeInterface) {
        if (current instanceof myType) {
            impl = current
            break;
        }
    }
    return impl;
}

在 Java 中可以吗?我应该使用仿制药吗?

首先,您需要所需 class 的 Class 实例(您已经提到“根据其 class 名称”)。您可以使用

从 class 名称中获取一个 Class 实例
Class<?> cls = SomeInterfaceImpl.class;

或者如果您将 class 名称作为字符串:

Class<?> cls = Class.forName("package.ClassName")

或来自使用

的实例
SomeInterfaceImpl myType = ...;
Class<?> cls = myType.getClass()

然后你可以调用这个方法,假设你有一个 List<SomeInterface> listOfThingsThatImplementsSomeInterface 某处:

private SomeInterface getThisType(Class<?> myType) {
    for (SomeInterface current: listOfThingsThatImplementsSomeInterface) {
        if (myType.isInstance(current)) {
            return current;
        }
    }
    return null; //nothing found
}

假设我们有想要的实现Class实例,(参考如果class是Class<?>),可以使用Stream来完成,

private <T extends SomeInterface> Optional<T> getThisType(Class<T> type) {
    return this.someInterfaceList.stream().filter(type::isInstance)
            .map(type::cast).findFirst();
}

匹配类型的关键是使用Class#isInstance
一些注意事项:

  1. 使方法 return 类型通用,因此不需要转换。
  2. Class#cast可以用来转换return类型的Stream。
  3. 使用Optional处理没有元素匹配的情况。

完整示例

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

public class FilterByClass {

    List<SomeInterface> someInterfaceList = new ArrayList<>();

    public static void main(String[] args) {
        FilterByClass filterByClass = new FilterByClass();
        filterByClass.someInterfaceList = List.of(new SomeInterfaceImplA(), new SomeInterfaceImplB(), new SomeInterfaceImplC());
        System.out.println(filterByClass.getThisType(SomeInterfaceImplA.class).get().name());
        System.out.println(filterByClass.getThisType(SomeInterfaceImplB.class).get().name());
        System.out.println(filterByClass.getThisType(SomeInterfaceImplC.class).get().name());
    }

    private <T extends SomeInterface> Optional<T> getThisType(Class<T> type) {
        return this.someInterfaceList.stream().filter(type::isInstance)
                .map(type::cast).findFirst();
    }

    public interface SomeInterface {
        default String name() {
            return this.getClass().getSimpleName();
        }
    }

    public static class SomeInterfaceImplA implements SomeInterface { }

    public static class SomeInterfaceImplB implements SomeInterface { }

    public static class SomeInterfaceImplC implements SomeInterface { }
}

该方法应将 class 作为参数。假设你的接口是 T,你可以接收类型为 Class<? extends T>

的参数

然后遍历列表并检查具有相同 class

的元素

这是一个应该有效的示例:

private static <T> Optional<T> getThisType(
        List<T> listOfThingsThatImplementsInterfaceT, 
        Class<? extends T> klass) {
    return listOfThingsThatImplementsInterfaceT.stream()
            .filter(klass::isInstance)
            .findFirst();
}

使用 Serializable

列表进行测试
List<Serializable> listOfThingsThatImplementsSerializable = Arrays.asList(
    new Integer(1), new Float(2), new Double(3)
);

System.out.println(
    getThisType(listOfThingsThatImplementsSerializable, Float.class)
);

寻找 Float returns Optional[2.0]