1

以下是我的接口定义

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 的子类型。

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

4

4 回答 4

3

因为正如你所写的那样,你的接口指定find()返回一个扩展Collection东西ICommon

您的实现正在返回Collection一个特定子类ICommon. 就编译器而言,这是一种未经检查的转换;如果Collection实际包含 的其他子类会发生什么ICommon

于 2011-12-27T04:28:51.310 回答
1

如果你的接口的目的是定义一个带有参数的 find 方法String name, boolean isExact,客户端将能够知道ICommon返回的特定元素(例如,客户端可以只抓取 aCollection<IOrganization>而不是 a Collection<? extends ICommon>,那么你的接口签名应该如下:

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)。

于 2011-12-27T05:34:26.627 回答
0

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

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

但是您的Collection<IOrganization> find(...方法与上述不兼容,因为它不返回 type Collection<SomeRandomClassImplementingICommon>

于 2011-12-27T07:37:14.777 回答
0

在定义时保持相同的签名,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);

T但是您在泛型方法中引入的参数类型<T extends ICommon>没有用,因为您在参数列表中没有。

可能是您可能想要的不是通用方法。但是如下:

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  
    }
}
于 2011-12-27T04:38:45.493 回答