- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在阅读 Java 教程中的以下部分:http://docs.oracle.com/javase/tutorial/java/generics/capture.html
它首先说明以下代码由于无法将捕获转换为对象而产生错误,因此 set
方法无法确认对象的类型为捕获#1:
import java.util.List;
public class WildcardError {
void foo(List<?> i) {
i.set(0, i.get(0));
}
}
我有点理解这背后的原因。 i.get 返回一个对象,并且编译器无法确定该对象是否属于 capture#1 类型,因此它无法以类型安全的方式将其与第二个参数匹配。
然后建议使用以下代码使此方法起作用:
public class WildcardFixed {
void foo(List<?> i) {
fooHelper(i);
}
// Helper method created so that the wildcard can be captured
// through type inference.
private <T> void fooHelper(List<T> l) {
l.set(0, l.get(0));
}
}
我有点明白为什么这段代码也能正常工作,在这段代码中,l.get
保证是 T 类型,所以它可以作为参数传递类型 T。
我不明白的是为什么你不能只使用这样的方法,没有帮助:
class GenericsTest {
static <K> void bar(List<K> l) {
l.set(0, l.get(l.size() - 1));
}
public static void main(String[] args) {
List<Integer> lst = Arrays.asList(1, 2, 3, 4);
bar(lst);
System.out.println(lst); // [4, 3, 2, 4]
}
}
即如果您要使用类型推断,为什么不直接使用显式类型泛型而不是通配符和辅助函数呢?在这种情况下使用通配符有什么好处吗?在哪些情况下您实际上更愿意使用通配符而不是类型泛型?
最佳答案
首先注意void foo(List<?> i)
和 void <K> foo(List<K> i)
两者都接受完全相同的参数集——假设您没有明确指定 K
在泛型方法的情况下,任何可以传递给一个函数签名的参数都可以传递给另一个函数签名,反之亦然。所以对于“外部代码”,两种签名都同样有用。
鉴于它们是等价的,类型参数较少的那个更简单,应该始终是首选。当向外部代码提供公共(public) API 时,您应该始终以最简单的形式提供它,只使用确保其安全所需的最少类型内容。类型List<?>
足以表达它可以接受任何类型的 List
, 所以这就是我们应该使用的。
我们碰巧使用了类型参数K
在内部解决一些泛型问题,但这只是一个不幸的内部实现细节,外部代码不需要关心。因此,我们应该在制作公共(public) API 时隐藏这种丑陋之处,并将其包装在更好的函数签名中。
除了抽象目的之外,您可能需要特定签名的另一个原因是它是否覆盖具有该签名的父类(super class)方法。覆盖时不能添加类型参数。
关于Java Generics Wildcard 与 Typed Generics 用法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25796921/
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 想改进这个问题?将问题更新为 on-topic对于堆栈溢出。 6年前关闭。 Improve this qu
我有实体: @Entity @Table(name = "CARDS") public class Card { @ManyToOne @JoinColumn(name = "PERSON_I
我正在尝试计算二维多边形的表面法线。我正在使用 OpenGL wiki 中的 Newell 方法来计算表面法线。 https://www.opengl.org/wiki/Calculating_a_S
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎与 help center 中定义的范围内的编程无关。 . 关闭 7 年前。 Improve
关闭。这个问题是off-topic .它目前不接受答案。 想改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 关闭 9 年前。 Improve this
我这里有以下 XML: Visa, Mastercard, , , , 0, Discover, American Express siteonly, Buyer Pay
即将发生的 Google 政策变更迫使我们实现一个对话框,以通知欧盟用户有关 Cookie/设备标识符用于广告和分析的情况。我只想向欧盟用户显示此对话框。我不想使用额外的权限(例如 android.p
本文分享自华为云社区《华为大咖说 | 企业应用AI大模型的“道、法、术” ——道:认知篇》,作者:华为云PaaS服务小智。 本期核心观点 上车:AGI是未来5~10年内,每个人都无法回避的技
我有一个与酒精相关的网站,需要先验证年龄,然后才能让他们进入该网站。我使用 HttpModule 来执行此操作,该模块检查 cookie,如果未设置,我会将它们重定向到验证页面。我验证他们的年龄并存储
在欧盟,我们有一项法律,要求网页请求存储 cookie 的许可。我们大多数人都了解 cookie 并同意它们,但仍然被迫在任何地方明确接受它们。所以我计划编写这个附加组件(ff & chrome),它
以下在 C 和/或 C++ 中是否合法? void fn(); inline void fn() { /*Do something here*/ } 让我担心的是,第一个声明看起来暗示函数将被定义
我是一名优秀的程序员,十分优秀!