如何通过实现名称从接口实现列表中获取元素
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
。
一些注意事项:
- 使方法 return 类型通用,因此不需要转换。
Class#cast
可以用来转换return类型的Stream。
- 使用
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]
我有一个 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<?> 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<?>
),可以使用Stream来完成,
private <T extends SomeInterface> Optional<T> getThisType(Class<T> type) {
return this.someInterfaceList.stream().filter(type::isInstance)
.map(type::cast).findFirst();
}
匹配类型的关键是使用Class#isInstance
。
一些注意事项:
- 使方法 return 类型通用,因此不需要转换。
Class#cast
可以用来转换return类型的Stream。- 使用
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]