快速业务通道

Java理论与实践: 使用通配符简化泛型使用 - 编程入门网

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-06-22
它不能检验 这个操作的安全性。由于 box 是一个 Box<?> 而不是一个原始的 Box, 编译器知道存在一些 T 充当 box 的类型参数,但由于不知道 T 具体是什么, 您不能调用 put() 因为不能检验这么做不会违反 Box 的类型安全限制(实际上 ,您可以在一个特殊的情况下调用 put():当您传递 null 字母时。我们可能不 知道 T 类型代表什么,但我们知道 null 字母对任何引用类型而言是一个空值 )。

关于 box.get() 的返回类型,unbox() 了解哪些内容呢?它知道 box.get() 是某些未知 T 的 T,因此它可以推断出 get() 的返回类型是 T 的擦除 (erasure),对于一个无上限的通配符就是 Object。因此清单 2 中的表达式 box.get() 具有 Object 类型。

Java理论与实践: 使用通配符简化泛型使用(2)

时间:2010-12-20 IBM Brian Goetz

通配符捕获

清单 3 展示了一些似乎应该 可以工作的代码,但实际上不能。它包含一个 泛型 Box、提取它的值并试图将值放回同一个 Box。

清单 3. 一旦将值从 box 中取出,则不能将其放回

public void rebox(Box<?> box) {    box.put(box.get()); } Rebox.java:8: put(capture#337 of ?) in Box<capture#337 of ?> cannot be applied   to (java.lang.Object)    box.put(box.get());     ^ 1 error

这个代码看起来应该可以工作,因为取出值的类型符合放回值的类型,然而 ,编译器生成(令人困惑的)关于 “capture#337 of ?” 与 Object 不兼容的 错误消息。

“capture#337 of ?” 表示什么?当编译器遇到一个在其类型中带有通配符 的变量,比如 rebox() 的 box 参数,它认识到必然有一些 T ,对这些 T 而言 box 是 Box<T>。它不知道 T 代表什么类型,但它可以为该类型创建一个 占位符来指代 T 的类型。占位符被称为这个特殊通配符的捕获(capture)。这 种情况下,编译器将名称 “capture#337 of ?” 以 box 类型分配给通配符。 每个变量声明中每出现一个通配符都将获得一个不同的捕获,因此在泛型声明 foo(Pair<?,?> x, Pair<?,?> y) 中,编译器将给每四个通配符的 捕获分配一个不同的名称,因为任意未知的类型参数之间没有关系。

错误消息告诉我们不能调用 put(),因为它不能检验 put() 的实参类型与其 形参类型是否兼容 — 因为形参的类型是未知的。在这种情况下,由于 ? 实际 表示 “?extends Object” ,编译器已经推断出 box.get() 的类型是 Object ,而不是 “capture#337 of ?”。它不能静态地检验对由占位符 “capture#337 of ?” 所识别的类型而言 Object 是否是一个可接受的值。

捕获助手

虽然编译器似乎丢弃了一些有用的信息,我们可以使用一个技巧来使编译器 重构这些信息,即对未知的通配符类型命名。清单 4 展示了 rebox() 的实现和 一个实现这种技巧的泛型助手方法(helper):

清单 4. “捕获助手” 方法

public void rebox(Box<?> box) {    reboxHelper(box); } private<V> void reboxHelper(Box<V> box) {    box.put(box.get()); }

助手方法 reboxHelper() 是一个泛型方法,泛型方法引入了额外的类型参数 (位于返回类型之前的尖括号中),这些参数用于表示参数和/或方法的返回值 之间的类型约束。然而就 reboxHelper() 来说,泛型方法并不使用类型参数指 定类型约束,它允许编译器(通过类型接口)对 box 类型的类型参数命名。

捕获助手技巧允许我们在处理通配符时绕开编译器的限制。当 rebox() 调用 reboxHelper() 时,它知道这么做是安全的,因为它自身的 box 参数对一些未 知的 T 而言一定是 Box<T>。因为类型

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号