泛型通配符:
例子:
interface AA{}
class BB{}
class A1 extends BB implements AA{}
class B1 extends A1{}
List<? extends BB> list = new ArrayList<A1>();
//list.add(new A1()); A1继承BB,但这里会编译报错The method add(capture#1-of ? extends BB) in the type List<capture#1-of ? extends BB> is not applicable for the arguments (A1)
List<? extends BB> list0 = new ArrayList<B1>();
list = list0;
解析:
list.add(new A1())之所以报错是因为不能确定list中的元素是什么类型,虽然此时它的确指向的是new ArrayList<A1>(),但编译器还没有智能到这种程度,知道list当前的元素类型。
List<? extends BB>只是一种引用声明,声明引用的List中的元素类型是继承BB的,但并不确定是何种类型(capture#1-of ? extends BB),所以list = list0并不会报错,
因为list和list0当中的元素都是继承BB的,符合(capture#1-of ? extends BB)的定义声明
List<? super B1> list2 = new ArrayList<A1>();
List<? super A1> list3 = new ArrayList<BB>();
//list3 = list2; //编译报错 Type mismatch: cannot convert from List<capture#2-of ? super B1> to List<? super A1>
list2 = list3;
解析:list2不能添加A1类型元素,因为A1是B1的父类,而list3可以添加A1类型元素,因此将list2赋给list3不正确。(add只能add与super同等级的或者为该等级子类的类型,尽管B1的直接超类就是A1,也不能添加A1类元素,只能认为编译器认为B1有可能实现不同的接口,譬如I1,单I1跟A1是没有继承关系的,所以如果集合是I1类型,那添加A1类型的元素肯定是错的)
list2=list3似乎有些别扭,因为list2的元素类型是super B1,即它可能是A1,而list3的元素类型是super A1,即它可能是BB,而将list3赋给list2似乎是将父类元素BB强转为A1,
这应该是报错才对,但我们要回到之前讨论的List<? super B1> 的意义是什么,它只是一种引用声明,声明引用的List的元素类型是super B1的(capture#1-of ? super B1),
至于是什么类型并不确定,它可以动态指向任何元素类型super A1的List。以下赋值声明也正确:
List<? super B1> list4 = new ArrayList<BB>(); //BB是B1的祖辈元素
List<? super B1> list2 = new ArrayList<A1>();
//list2.add(new A1()); 编译报错The method add(capture#1-of ? super B1) in the type List<capture#1-of ? super B1> is not applicable for the arguments (A1)
解析:
list2的元素实体明明是用了装A1类型的,但添加A1却报错,这是因为List<? super B1>也可能指向new ArrayList<B1>(),此时直接添加父类元素A1当然报错了
总结:
1.List<? super AA> list2 = new ArrayList<AA>();//List<? super AA> list2 = new ArrayList<B1>();这个声明会报错
2.list2.add(new B1());
1和2要的时机是不同的,1是声明,2是往堆内存添加实际对象。
声明时创建的集合泛型类型要直接符合通配符的父子声明;
添加时看是否会存在一种符合通配符的类型A(不用看实际指向的堆内存存的是什么类型的数据),添加的元素类型与类型A不兼容,若无则可添加该类型元素。
相关推荐
在Java编程语言中,通配符(Wildcard)是一种强大的工具,它允许我们在处理类型参数时增加灵活性和泛用性。通配符主要出现在泛型的上下界声明中,帮助我们处理多种类型的对象,而不必为每种类型创建单独的方法或类。...
Java 通过通配符查找文件 例如:*.*, *.java, a*.*, a*.java
Java泛型通配符是Java编程语言中一个重要的特性,它允许我们在定义泛型类型时使用问号(?)作为占位符,表示任意类型的参数。这种通配符的使用大大提高了代码的灵活性和可复用性,同时也帮助开发者遵循强类型检查的...
Java类型通配符应用实战分析 Java类型通配符是Java泛型系统中的一种重要机制,它允许开发者在编写泛型代码时更加灵活和安全。本文将详细介绍Java类型通配符的概念、原理和应用实战,帮助读者更好地理解和应用Java...
正则表达式通配符.jpg正则表达式通配符.jpg正则表达式通配符.jpg正则表达式通配符.jpg正则表达式通配符.jpg正则表达式通配符.jpg
* 一个参数通配符的实例 * 说明:对一个包含了数值元素的集合进行汇总运算。在这种情况下,用户并不关心 * 集合中的每一个对象是什么类型,只要它是数值型即可,而且,用户也希望集合中可以 * 存放不同类型的数值...
Java使用路径通配符加载Resource与profiles配置使用详解 本文主要介绍了Java使用路径通配符加载Resource与profiles配置使用详解。通过示例代码,详细介绍了Java使用路径通配符加载Resource与profiles配置的使用方法...
Java泛型中T和问号(通配符)的区别 Java泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、...
java基础-泛型通配符
本篇文章将详细探讨如何在易语言中实现文本匹配通配符的功能。 通配符是一种特殊的字符或字符串,用于表示一组可能的字符组合,常用于文件名搜索、正则表达式等场景。常见的通配符有星号(*)和问号(?)。星号代表零个...
### 泛型类、通配符的使用及上下限详解 #### 1. 泛型类的概念 在Java中,泛型是一种使代码更加灵活、重用性更强且类型安全的技术。通过使用泛型,我们可以定义类型参数化的类或方法,从而避免了代码重复并且可以在...
Java泛型通配符T、E、K、V区别详解 Java泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口...
子网掩码和通配符掩码是网络管理员在配置IP网络时不可或缺的工具,用于定义网络和主机的边界,优化IP地址的使用。本文将深入探讨这两个概念以及相关的计算方法。 子网掩码(Subnet Mask)是IPv4网络中用于识别网络...
网上只看到有通配符查找,返回boolean值的,为进行补充,单独写了一个通配符查找单元MatchFind,主要的为MatchFindStr(MainStr,SubStr)函数,返回符合条件的通配符的字符。 奇怪的是在winxp下,微软的查找中文使用...
java泛型常用通配符实例解析 Java泛型是Java 5中引入的一项新特性,可以用来编写泛型代码,使得代码更加灵活和可重用。其中,通配符是泛型中的一种重要概念,本文将详细介绍Java泛型常用通配符实例解析。 1. 限定...
sql中经常用like进行模糊查询,而模糊查询就要用到百分号“%”,下划线“_”这些通配符,其中“%”匹配任意多个字符,“_”匹配单个字符。如果我们想要模糊查询带有通配符的字符串,如“60%”,“user_name”,就...
Java泛型初学者之上、下界通配符的深入理解 Java泛型初学者之上、下界通配符的深入理解主要介绍了Java泛型的相关知识,包括泛型的由来、泛型的语法、泛型的应用场景、泛型的缺点以及上、下边界通配符的理解等。 ...
Java 中的通配符(Wildcard)是一种特殊的类型参数,它可以表示一个未知的类型。通配符类型可以用在泛型类、接口、方法和变量中,用于表示泛型类型的未知部分。 在 Java 中,通配符类型的使用可以分为三种情况: 1...
带通配符的字符串匹配算法则是这个领域的延伸,它允许在模式字符串中包含特殊字符,如星号(*)或问号(?),以表示任意字符或单个任意字符。这种算法使得搜索更加灵活,可以适应更复杂的查询需求。 **通配符的含义** -...
Java中泛型通配符的使用方法示例 Java 中泛型通配符的使用方法示例主要介绍了 Java 中泛型通配符的使用方法,结合实例形式分析了 Java 中泛型通配符的功能、语法及在泛型类创建泛型对象中的使用方法。以下是 Java ...