【问题标题】:Unchecked conversion warning未经检查的转换警告
【发布时间】:2011-12-27 04:21:39
【问题描述】:

以下是我的接口定义

interface IStorage {
   <T extends ICommon> Collection<T> find(String name, boolean isExact);
}

这就是实现

Storage implements IStorage {
    Collection<IOrganization> find(String name, boolean isExact) {
       //some code
    }
}

IOrganization 是 ICommon 的子类型。

为什么我仍然会看到未经检查的转化警告?

【问题讨论】:

    标签: java generics unchecked


    【解决方案1】:

    因为正如您所写,您的界面指定 find() 返回一个扩展 ICommon

    somethingCollection

    您的实现正在返回ICommon特定子类Collection。就编译器而言,这是一种未经检查的转换;如果Collection 实际上包含ICommon 的其他子类会怎样?

    【讨论】:

      【解决方案2】:

      如果您的接口的目的是使用String name, boolean isExact 的参数定义一个查找方法,客户端将能够知道正在返回ICommon 的哪个特定元素(例如,客户端可以获取一个Collection&lt;IOrganization&gt; 而不是Collection&lt;? extends ICommon&gt;,那么你的接口签名应该如下:

      interface IStorage<T extends ICommon> {
      Collection<T> find(String name, boolean isExact);
      }
      

      然后实现更改为以下内容:

      class Storage implements IStorage<IOrganization> {
      Collection<IOrganization> find(String name, boolean isExact) {
      return null; // whatever you would return.
      }
      }
      

      请注意,这不同之处在于您定义了一个接口,该接口声明了要通过 find 方法返回的特定类型,而之前只能说返回了 ICommon 类型或某个未知子类型,所以如果您尝试强制转换为 ICollection,编译器无法验证您是否始终可以执行此操作(如果您给它一个不是 ICollection 的实现,您可能会在运行时收到 ClassCastException)。

      【讨论】:

      • 是的。创建一个通用接口是合理的。
      【解决方案3】:

      在定义 Storage 时保持相同的签名,因为您仍在定义方法 find(而不是使用它):

      Storage implements IStorage {
          <T extends ICommon> Collection<T> find(String name, boolean isExact) {
             //some code
          }
      }
      

      您将在实际调用该泛型方法时指定具体类型参数:

      Storage s = new Storage();
      s.<IOrganization>find("hello world", true);
      

      但是您在泛型方法中使用&lt;T extends ICommon&gt; 引入的参数类型T 没有用,因为您在参数列表中没有。

      可能你想要的不是泛型方法。但是如下:

      interface IStorage {
          public Collection<? extends ICommon> find(String name, boolean isExact);
      }
      
      //and
      class Storage implements IStorage {
          public Collection<IOrganization> find(String name, boolean isExact) {
              //some code                
          }
      }
      
      //or 
      class Storage implements IStorage {
          public Collection<? extends ICommon> find(String name, boolean isExact) {
              //some code  
          }
      }
      

      【讨论】:

        【解决方案4】:

        当你有一个像&lt;T extends ICommon&gt; Collection&lt;T&gt; find(... 这样的泛型方法时,这意味着调用者可以要求 T 是他们想要的任何东西。这意味着该方法必须适用于任何此类 T,而不是能够选择特定的 T(您似乎想要做的)。为了演示,您的通用方法允许调用者说

        IStorage obj = ...;
        Collection<SomeRandomClassImplementingICommon> foo = obj.find(...);
        

        但是您的Collection&lt;IOrganization&gt; find(... 方法与上述不兼容,因为它不返回类型Collection&lt;SomeRandomClassImplementingICommon&gt;

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-10-05
          • 1970-01-01
          相关资源
          最近更新 更多