4

我想知道是否存在一个库来执行一堆平凡的演员表(基本上是一堆潜在的不安全演员表的包装,在大多数情况下,这在实践中不是问题)。例如,假设我在库中有以下内容(为简洁起见省略了正文):

public interface LibraryInterface;

public static void doSomething(Collection<LibraryInterface> collection);

所以doSomething()固执地只需要一些不如可能灵活的东西(即。。Collection<? extends LibraryInterface>是否有一个库提供与以下相同的功能:

public static <T, U extends T> Collection<T> cast(Collection<U> collection);

因此,如果我有一个实现的类LibraryInterface,并且我有一个List<MyLibraryInterfaceImpl>,我仍然可以doSomething()通过强制转换该列表来使用?(的主体cast()暗示包含不安全的演员表,但至少从用户的角度来看,演员表被隐藏起来,或者集中在一个地方)。

(也很好,与比较器之类的东西相反)

4

3 回答 3

1

现在,这样的图书馆会做什么?

void flexibleDoSomething(Collection<? extends LibraryInterface> collection) {
    doSomething((Collection<LibraryInterface>) collection);
}

这种方法看起来不值得一个图书馆。这样做不会获得任何额外的类型安全性。显然,更好的办法是首先修复另一个库。但是您始终可以内联该方法。

在某些情况下,我见过这样的库正在使用中。主要是为了让演员在频繁出现时集中在一个类中,或者因为其中一些在语法上混乱。例如,转换Class<Foo<?>>Class<Foo<Something>>复杂的泛型。

请注意,使用泛型时,每种类型都应出现在右侧,以确保编译器正确绑定它。

public static <T, U extends T> Collection<T> cast(Collection<U> collection);

对于这种方法,编译器会很高兴地假设它TObject.

要获得更严格的泛型,您可能需要使用类似的东西

public static <T, U extends T> Collection<T> cast(Collection<U> collection, Class<T> clz);

这样,您实际上可以指定T, 和(好吧,不是针对Collection,而是针对其他情况),实用程序方法还可以进行一些类型检查。

于 2012-11-21T07:16:41.060 回答
1

您的方法所做的一切都cast(Collection<U> collection)可以通过<T extends LibraryInterface> doSomething(Collection<T> collection)

图书馆的额外点是什么?

而且,如果 API 构建者决定让类型保持不变,那么这基本上意味着他严格希望您遵守合同并仅提供LibraryInterface或设计用于特定用途。在 Java 泛型中type erasure你也可以这样做

List<? extends Object> p = new ArrayList<Object>();

但是现在List<? extends Object> p = new ArrayList<? extends Object>(); 以上是非法的。所以首先没有类型转换和循环,我不知道实现这样一个库的任何其他方式。

因此,对于您想要做的事情,如果泛型是协变的,那就是

List<Object> p = new ArrayList<String>();

任何你想要的任何目的都是可能的。但上述说法是非法的。因此你不能忽略它。

因此,执行上述操作的唯一方法是循环并检查,然后最终键入 cast。

更多信息可以在这里这里找到

于 2012-11-21T06:44:14.960 回答
1

这样的图书馆将是无稽之谈。由于类型擦除,强制转换为父类绝对没有任何作用,除了删除编译器警告。此外,图书馆会做的是直接做演员表或复制馆藏。换句话说,它要么做你不想做的事,并激励你使用这个库,要么做一些非常低效和无用的事情......

如果您想在进行不安全转换之前检查集合的内容,则向下转换更有意义。您可以创建一个函数来遍历集合以检查所有元素的类型,然后通过执行不安全强制转换返回集合。您可以在 ~3 行中编写此函数;)。

于 2012-11-21T06:34:52.010 回答