Java 如何通过类的方法实现动态查找类?
我有一个类类型列表。我想找到一个适合处理不同值的特定类 在下面的示例中,每个实现都必须提供一个Java 如何通过类的方法实现动态查找类?,java,arraylist,interface,Java,Arraylist,Interface,我有一个类类型列表。我想找到一个适合处理不同值的特定类 在下面的示例中,每个实现都必须提供一个supports(String)方法。并定义该类支持哪些值 问题:列表中没有对象,只有类类型。因此,我无法对它们调用像supports()这样的自定义方法 List<Class<MyService>> list; public Object getInstanceThatSupports(String val) { val = "TEST"; for (Class
supports(String)
方法。并定义该类支持哪些值
问题:列表中没有对象,只有类类型。因此,我无法对它们调用像supports()
这样的自定义方法
List<Class<MyService>> list;
public Object getInstanceThatSupports(String val) {
val = "TEST";
for (Class<MyService> c : list) {
if (c.supports(val)) { //TODO this is invalid
return c.newInstance().process(val);
}
}
}
public interface MyService {
boolean supports(String val);
void process(String val);
}
public class MyServiceImpl implements MyService {
@Override
public boolean supports(String val) {
return val.equals("TEST");
}
@Override
public void process(String val) {
//handle the value
}
}
列表;
公共对象getInstanceThatSupports(字符串val){
val=“测试”;
用于(c类:列表){
如果(c.supports(val)){//TODO,则此操作无效
返回c.newInstance().process(val);
}
}
}
公共接口MyService{
布尔支持(字符串val);
作废处理(字符串val);
}
公共类MyServiceImpl实现了MyService{
@凌驾
公共布尔支持(字符串val){
返回值等于(“测试”);
}
@凌驾
公共作废处理(字符串val){
//处理值
}
}
我怎样才能做到这一点呢?您应该改为
List
,因为您需要调用列表中所有元素的方法
List<MyInterface> list = Arrays.asList(new MyImpl(), new MyImpl2());
String val = "TEST";
for (MyInterface x : list) {
if (x.supports(val)) {
//TODO
}
}
List List=Arrays.asList(new MyImpl(),new MyImpl2());
字符串val=“测试”;
对于(MyInterface x:list){
如果(x.支持(val)){
//待办事项
}
}
您应该改为List
,因为您需要调用列表中所有元素的方法
List<MyInterface> list = Arrays.asList(new MyImpl(), new MyImpl2());
String val = "TEST";
for (MyInterface x : list) {
if (x.supports(val)) {
//TODO
}
}
List List=Arrays.asList(new MyImpl(),new MyImpl2());
字符串val=“测试”;
对于(MyInterface x:list){
如果(x.支持(val)){
//待办事项
}
}
考虑到MyService的API,您的请求无法实现
确定给定类是否支持字符串值的唯一方法是调用supports()
,这是一个非静态方法。因此,您必须创建一个实例才能调用它
Java不允许在接口中定义静态方法
我的建议是不要反对这一点,并将其视为您的设计有问题的迹象。你最好不要有一个类
的列表,而是有一个MyInterface
的列表。将它们设置为无状态且可重入,然后您可以轻松调用supports()
和process()
这是一种非常常见的模式,尤其是在Spring这样的框架中。您应该在初始化时创建MyInterface
对象列表,并在程序的生命周期中重用它
如果每次都必须创建一个新实例,请为每个实例创建一个相应的factory对象,并创建一个MyInterfaceFactory
列表,而不是类型列表:
public class MyInterfaceImplFactory implements MyInterfaceFactory {
public boolean supports(String s) {
// hard code this here
}
public MyInterfaceImpl newInstance() {
return new MyInterfaceImpl();
}
}
(如果你有这么多这样的东西,以至于写它们变得重复,你可以更动态地去做——但从愚蠢的方式开始)
如果确定要有一个类列表,可以在运行时检查:
- 您可以对接口中未声明的静态
方法进行标准化。您必须通过反射来调用它,而不必使用Java的类型安全性supports()
- 您可能可以使用自定义注释执行某些操作
但是,如果你有任何自由,就不要做这两件事。考虑到你MyService的API,你所要求的是做不到的 确定给定类是否支持字符串值的唯一方法是调用
supports()
,这是一个非静态方法。因此,您必须创建一个实例才能调用它
Java不允许在接口中定义静态方法
我的建议是不要反对这一点,并将其视为您的设计有问题的迹象。你最好不要有一个类
的列表,而是有一个MyInterface
的列表。将它们设置为无状态且可重入,然后您可以轻松调用supports()
和process()
这是一种非常常见的模式,尤其是在Spring这样的框架中。您应该在初始化时创建MyInterface
对象列表,并在程序的生命周期中重用它
如果每次都必须创建一个新实例,请为每个实例创建一个相应的factory对象,并创建一个MyInterfaceFactory
列表,而不是类型列表:
public class MyInterfaceImplFactory implements MyInterfaceFactory {
public boolean supports(String s) {
// hard code this here
}
public MyInterfaceImpl newInstance() {
return new MyInterfaceImpl();
}
}
(如果你有这么多这样的东西,以至于写它们变得重复,你可以更动态地去做——但从愚蠢的方式开始)
如果确定要有一个类列表,可以在运行时检查:
- 您可以对接口中未声明的静态
方法进行标准化。您必须通过反射来调用它,而不必使用Java的类型安全性supports()
- 您可能可以使用自定义注释执行某些操作
但是,如果您有任何自由,请不要执行这两项操作。您可以创建一个注释
@支持
,例如,您可以使用该注释对实现进行注释
此注释可能如下所示:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Supports {
String value();
}
使用
Class.isAnnotationPresent
可以检查实现是否具有所需的注释,使用Class.getAnnotation
可以获得注释并访问值()
方法获取支持的值。您可以创建一个注释@Supports
,例如,您可以使用该注释对实现进行注释
此注释可能如下所示:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Supports {
String value();
}
通过使用
Class.isAnnotationPresent
可以检查实现是否具有所需的注释,使用Class.getAnnotation
可以获得注释,并可以访问value()
方法来获得支持的值。使用反射可以是一种方法,但不太清楚您想要什么。如果我的输入值是TEST
,我想找到支持的MyService
实现