【问题标题】:Instantiate Java classes which implements specific Interface using reflection使用反射实例化实现特定接口的 Java 类
【发布时间】:2013-01-18 19:27:53
【问题描述】:
我是反射的新手。我看过一些问题和教程。
假设我有一个由 3 个类 A、B、C
实现的接口
public interface MyInterface {
doJob();
}
现在使用反射我想调用每个类
Class<?> processor = Class.forName("com.foo.A");
Object myclass = processor.newInstance();
我不能将整个过程限制为特定类型,而不是创建一个对象。
我只想调用 MyInterface 类型的类。
如果我传递 com.foo.A 它应该创建 A 类对象,com.foo.B 应该创建 B 类对象,但是如果我传递一些存在但仍然没有实现 MyInterface 的 com.foo.D 不应该不会被调用。
我怎样才能做到这一点?
【问题讨论】:
标签:
java
class
reflection
interface
【解决方案1】:
试试下面的代码
package com.rais.test;
public class Client {
public static void main(String[] args) {
try {
System.out.println(createObject("com.rais.test.A"));
System.out.println(createObject("com.rais.test.D"));
} catch (Exception e) {
e.printStackTrace();
}
}
public static MyInterface createObject(String className)
throws ClassNotFoundException, InstantiationException,
IllegalAccessException {
Class<?> clazz = Class.forName(className);
if (MyInterface.class.isAssignableFrom(clazz)) {
return (MyInterface) clazz.newInstance();
} else {
throw new RuntimeException(
"Invalid class: class should be child of MyInterface");
}
}
【解决方案2】:
嗯,Java 反射是一种通用机制,因此如果您只使用问题中提供的代码,则无法实现您想要实现的目标。
这就像询问如何限制 Java 创建类型对象而不是实现“MyInterface”的对象。 Java 的“新”是通用的,它允许创建您想要的任何对象。
一般来说,您可以为此编写自己的代码。
而不是直接调用
Class.forName
调用你自己的代码
你可以在编译时/运行时实现类似的东西。
编译类型检查示例(您需要创建一个 Class 对象):
public T newInstance(Class<T extends MyInterface cl) {
return cl.newInstance();
}
Evgeniy Dorofeev 已经发布了运行时示例
希望对你有帮助
【解决方案3】:
试试
MyInterface newInstance(String className) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
Class<?> cls = Class.forName(className);
if (!MyInterface.class.isAssignableFrom(cls)) {
throw new IllegalArgumentException();
}
return (MyInterface) cls.newInstance();
}