java - 使用 Java 接口(interface)作为参数强制执行严格(更好)类型安全的想法

标签 java generics interface type-safety

根据以下输入进行更新。我时常感到 Java 接口(interface)的类型安全使用的努力并不那么简单。

这是我们想要做的一个简单示例:设计,如下。在多次尝试获得类型安全之后,当谈到实现时,我(再次)发现我们需要用 Java 来思考,以鼓励 Java 来支持我们的需求。我对原始示例进行了改进。我将这个问题悬而未决,因为可能有更好的方法来解决问题。

意图:

  1. 考虑一些我们想要放入哈希中的不同类。
  2. 我们希望将它们作为 ServiceProvider 接口(interface)实例的集合进行管理。
  3. 这个想法是进行这样的 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 包装在方法中可以提供一些保护。

    继续致力于从相关的示例中提取类型保护:

    两者都不像我们正在寻找的东西()。这或类似的事情可能吗?我正在寻找有关如何做的想法?非常感谢您抽出时间。

    最佳答案

    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/

    相关文章:

    c# - 将接口(interface)映射到不实现接口(interface) C# 的类(动态)

    c# - 当(当前)只有一个实现它的类时,您是否应该创建一个接口(interface)?

    java - 在 Java 8 中使用三元运算符的泛型编译错误,但在 Java 7 中没有

    c# - 工厂方法和泛型

    java - 从抽象类调用非静态方法时遇到问题

    java - 如何停止循环然后继续?

    c# - 如何从 List<Tuple<int, int, string>> 获取字符串数组?

    java - 如何在 Java 的数据源中实现 getConnection()?

    java - 多线程调用单例方法会影响局部变量吗?

    java - 如何计算当前在我的应用程序中打开的第三方应用程序的时间