4

我正在用Java语言开发一个 Web 应用程序,它由一个系统和一些模块组成。它们都实现了IAppIdentifier接口,我将所有模块引用和系统本身存储在List系统中。

这个想法是这样设计的,如果每个模块都有所需的接口(从 IAppIdentifier 扩展),它们将能够访问系统本身或其他模块,因此它们必须向系统询问它们。

我有这个有效的代码:

@Override
public IAppIdentifier moduleByClass(Class<? extends IAppIdentifier> clazz) {
    List<IAppIdentifier> iApps = this.get_Iapps();
    for (IAppIdentifier iApp : iApps) {
        if (clazz.isAssignableFrom(iApp.getClass())) {
            return iApp;
        }
    }
    return null;
}

基本上它正在检查数组中的每个类是否可以从所需的接口分配,如果是,它将返回该实例。但是问题是我必须在方法返回它时强制转换它。

例如,我必须实现类似的东西来获取系统的实例:

((ISystem) this.get_Service().moduleByClass(ISystem.class))

我的问题是,在 java 中有什么方法可以避免再次进行这种转换,ergo,以确保它返回与我在编译时作为参数传递的相同类型?

4

1 回答 1

5

将方法签名更改为此:

public <T extends IAppIdenfitier> T moduleByClass(Class<T> clazz)

这应该有效。

即使您interface不是泛型的,您仍然可以在方法中使用泛型来实现它们自己的目的。通过此代码,您提供了T必须是IAppIdentifier自身或必须扩展它的通用规则。您的方法现在将返回类型的对象T并作为参数类作为Class<T>.

然后在您的代码中,每当您调用方法时,moduleByClass您不必强制转换它,例如:

ISystem = this.get_Service().moduleByClass(ISystem.class);

这里不需要演员,一切都会编译。

根据@XtremeBiker 的好评,还需要更多信息。在moduleByClass方法内部,需要将结果类型转换为T. 所以它是:

return iApp;

但现在应该是:

return clazz.cast(iApp);

无论如何,在方法体内进行就地转换比每次调用该方法时都进行转换更不烦人。

于 2013-01-31T09:09:35.347 回答