3

我是反射的新手。我看过一些问题和教程。

假设我有一个由 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 不应该被调用.

我怎样才能做到这一点?

4

3 回答 3

6

尝试

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();
}
于 2013-02-04T05:45:42.377 回答
2

好吧,Java 反射是一种通用机制,所以如果您只使用问题中提供的代码,就无法实现您想要实现的目标。这就像询问如何限制 Java 创建类型对象而不是实现“MyInterface”的对象。Java 的“新”是通用的,它将允许创建您想要的任何对象。

通常,您可以为此编写自己的代码。而不是直接调用

Class.forName

调用自己的代码

您可以在编译时/运行时实现类似的东西。

编译类型检查示例(您需要创建一个 Class 对象):

public T newInstance(Class<T extends MyInterface cl) {
  return cl.newInstance();
}  

Evgeniy Dorofeev 已经发布了运行时示例

希望这可以帮助

于 2013-02-04T05:47:42.383 回答
0

试试下面的代码

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

}
于 2013-02-04T06:02:30.553 回答