根据以下输入进行更新。我时常感到 Java 接口(interface)的类型安全使用的努力并不那么简单。
这是我们想要做的一个简单示例:设计,如下。在多次尝试获得类型安全之后,当谈到实现时,我(再次)发现我们需要用 Java 来思考,以鼓励 Java 来支持我们的需求。我对原始示例进行了改进。我将这个问题悬而未决,因为可能有更好的方法来解决问题。
意图:
- 考虑一些我们想要放入哈希中的不同类。
- 我们希望将它们作为 ServiceProvider 接口(interface)实例的集合进行管理。
- 这个想法是进行这样的 OO 设计:
服务类型:
public interface DisplaySettings extends ServiceInterface { ... }
提供商类型:
public interface ServiceProvider extends ServiceInterface { ... }
实现:
public class DisplayConfig extends Config
implements DisplaySettings, ServiceProvider
{ ... }
当我们想要“注册”一个实现时,挑战就来了。这是所需方法的方法原型(prototype):
public boolean registerService( final ServiceProvider newProvider ) { ... }
- newProvider实现的服务由:newProvider.getServiceInterface()给出
我们想按如下方式调用这种方法:
ServicesMgr.registerServiceProvider( this );
感谢下面的建议,请求注册提供者的模式是指定接口(interface),如下所示:
DisplaySettings videoSettings = ServicesMgr.getProvider( DisplaySettings.class );
当然,你不能这样做!编译的唯一替代方法是使用“.class”来注册和查找提供者实例对象。除了对上面的整洁定义进行必要的更改之外......
DisplaySettings videoSettings = ServicesMgr.getProvider( DisplaySettings.class );
这看起来更加类型安全。
按照@immibis的建议进行获取提供者调用...
public <InterfaceType extends ServiceInterface> ServiceProvider getProvider( Class<InterfaceType> interfaceClass )
{ ... }
遗憾的是,该解决方案不允许 HashMap 在查找提供程序时“找到”提供程序。看起来 HashMap 将使用不标识实现类的“类”。我尝试了一些变化,例如:
public Class<ServiceInterface> getServiceType(){ ... }
并使用上面的 InterfaceType。我对正在发生的事情的理解是,这具有挑战性,因为只有单一继承。 Class
不是:Class
,其中:
<InterfaceType extends ServiceInterface>
目前我只能使用:public Class getServiceType(){...}
作为一致的键。当然,由于我们只将“类”作为一种类型,因此它会导致类型安全性失效。通过将 getServiceType
包装在方法中可以提供一些保护。
继续致力于从相关的示例中提取类型保护:
- Type-safe Hetrogenous Container Pattern
- Enforcing parameter types on dependent interfaces?
- In Java HashMap, how to enforce a generic type to be a subclass
两者都不像我们正在寻找的东西(还)。这或类似的事情可能吗?我正在寻找有关如何做的想法?非常感谢您抽出时间。
最佳答案
DisplaySettings videoSettings = ServicesMgr.getProvider( DisplaySettings.class );
是有效的代码,并且类型安全,如果 getProvider
定义如下:
public <InterfaceType extends ServiceInterface> InterfaceType getProvider(Class<InterfaceType> interfaceClass) {
...
}
这应该很容易实现。
您的 registerServiceProvider
方法在概念上看起来也很复杂,但我没有看到您对此提出任何问题。
关于java - 使用 Java 接口(interface)作为参数强制执行严格(更好)类型安全的想法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26668135/