gpt4 book ai didi

java - 为什么我应该优先使用通配符而不是类型参数?

转载 作者:搜寻专家 更新时间:2023-11-01 03:19:00 24 4
gpt4 key购买 nike

我正在阅读 Effective Java 第 2 版,在 Item 28: Use bounded wildcards to increase API flexibility 中有以下内容:

// Two possible declarations for the swap method

public static <E> void swap(List<E> list, int i, int j);
public static void swap(List<?> list, int i, int j);

Which of these two declarations is preferable, and why? In a public API, the second is better because it’s simpler. You pass in a list—any list—and the method swaps the indexed elements. There is no type parameter to worry about. As a rule, if a type parameter appears only once in a method declaration, replace it with a wildcard.

我使用无界类型参数对其进行了测试,我没有看到任何缺点,我可以传递任何列表并且类型参数没有问题,实际上无界类型参数更好,因为我不需要助手方法如序列中所述:

there is a way to implement this method without resorting to an unsafe cast or a raw type. The idea is to write a private helper method to capture the wildcard type. The helper method must be a generic method in order to capture the type. Here’s how it looks:

public static void swap(List<?> list, int i, int j) {
swapHelper(list, i, j);
}
// Private helper method for wildcard capture
private static <E> void swapHelper(List<E> list, int i, int j) {
list.set(i, list.set(j, list.get(i)));
}

最后,这是我使用类型参数的实现:

 public static <E> void swap(List<E> list, int i, int j) {
list.set(i, list.set(j, list.get(i)));
}

和用法:

List<Object> integers = (...)
swap(integers, 1,2);

那么,为什么我要改用通配符呢?

问题是:为什么第二种方式更简单?我不明白为什么!我错过了一些细节?我真的很想明白 Bloch 的意思。

最佳答案

首先,了解 Bloch 在这里提出关于偏好的主张 - 你不一定非要同意他的观点(而且我亲眼目睹了关于这一点的长期而艰巨的讨论,所以你不是唯一一个)。

不过,他确实阐明了为什么他认为这样更好。我将尝试提取他的要点,使它们更清晰。

In a public API, the second is better because ... there is no type parameter to worry about. As a rule, if a type parameter appears only once in a method declaration, replace it with a wildcard....

This slightly convoluted implementation ... allows us to export the nice wildcard-based declaration....

Using wildcard types in your APIs, while tricky, makes the APIs far more flexible.

换句话说,Bloch 认为需要 E 类型是您不应该向客户端公开的实现细节 - swap() 方法应该适用于任何 List 因此 ? 是“正确的”并且公开 E 对用户没有任何好处。从某种意义上说,这是对条款 52:通过接口(interface)引用对象的概括。

请特别注意,此建议仅针对公共(public) API。无需仅在您调用的代码中实现此解决方法。

这个例子也可以说是人为设计的——这两种解决方案之间确实没有太大区别,但希望您能想象出更复杂的方法,它们需要通用类型作为其实现的一部分,而不是它们的公共(public)签名。 Bloch 的一般观点是,当用户不需要了解泛型类型时,您无需将这些知识强加给他们,即使这样做看起来微不足道。

关于java - 为什么我应该优先使用通配符而不是类型参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37040093/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com