• 欢迎访问天天编码网站,Java技术、技术书单、开发工具,欢迎加入天天编码
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏天天编码吧
  • 我们的淘宝店铺已经开张了哦,传送门:https://shop145764801.taobao.com/

深入讲解Java泛型中通配符的功能

Java高级 tiantian 1607次浏览 0个评论 扫描二维码

了解Java泛型的读者可能知道,一个包含有无限通配符的 Set< ? > 可以存储任何数据类型的元素。同时,一个原始的 Set< ? > 也可以存储任何数据类型的元素。那么,各位读者是否能够明白它们之间的区别和联系呢?在具体的编程实践中,我们更应该选择哪个方式呢?本文将深入浅出地阐述该问题。

深入讲解Java泛型中通配符的功能

Set< ? >

关于 Set< ? >,有两个事实需要读者知道:
1. 因为 “?” 代表这任意类型,所以 Set< ? > 可以存储任何类型的元素。
2. 因为完全不知道 “?” 代表的具体是什么类型,所以无法往 Set< ? > 添加任何元素。

所以,Set< ? >可以存储任意类型的元素,同时,没有办法往其中添加任何元素。这么看起来,这两个事实之间是相互冲突的。当然,实际情况并不是这样。我们通过以下的两个代码示例可以清晰地辨别和理解它们。

事实一的代码示例

//Legal Code
public static void main(String[] args) {
HashSet s1 = new HashSet(Arrays.asList(1, 2, 3));
printSet(s1);

HashSet s2 = new HashSet(Arrays.asList("a", "b", "c"));
printSet(s2);
}

public static void printSet(Set<?> s) {
for (Object o : s) {
System.out.println(o);
}
}

因为 Set< ? > 可以存储任何类型的元素,所以上述例子中直接使用了 Object。

事实二的代码示例

//错误代码
public static void printSet(Set<?> s) {
s.add(10);//这行代码是非法的
for (Object o : s) {
System.out.println(o);
}
}

因为我们不知道 <?> 所代表的具体类型,所以不能往 Set< ? > 添加除了 null 之外的任何元素。同样的原因,我们不能初始化一个类型为 Set< ? > 的集合。比如:

// 这个代码是非法的
Set<?> set = new HashSet<?>();

Set vs Set< ? >

在功能上,Set 与 Set< ? > 非常地相似,那么它们之间到底有什么区别呢?我们再看一个示例代码:

public static void printSet(Set s) {
s.add("2");
for (Object o : s) {
System.out.println(o);
}
}

可以看到这个使用 Set 的示例代码与使用 Set< ? > 的示例代码非常相似,但是这个示例代码是正确的。所以说,原始类型的 Set 没有任何的约束条件。但是,这样的使用方式很容易破坏 Collection 的不变约束。

总的来说,通配符的 Set< ? > 是类型安全的,而原始类型的 Set 是类型不安全的。

Set< ? > 的作用

&mesp;使用泛型机制,又希望保持类型安全,而且不知道或者不关心参数的具体类型时,就应该考虑使用通配符形式的 Set< ? >,它也仅仅只能作为方法的参数被使用。

public static void main(String[] args) {
HashSet s1 = new HashSet(Arrays.asList(1,2,3));
HashSet s2 = new HashSet(Arrays.asList(4,2,3));

System.out.println(getUnion(s1, s2));
}

public static int getUnion(Set<?> s1, Set<?> s2){
int count = s1.size();
for(Object o : s2){
if(!s1.contains(o)){
count++;
}
}
return count;
}

天天编码 , 版权所有丨本文标题:深入讲解Java泛型中通配符的功能
转载请保留页面地址:http://www.tiantianbianma.com/java-generic-wildcard.html/
喜欢 (4)
支付宝[多谢打赏]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址