您的位置:首页 > 职场人生

黑马程序员--Java基础加强--05.【泛型通配符】【个人总结】

2013-07-29 14:41 771 查看

泛型通配符   总结

----------- android培训java培训、java学习型技术博客、期待与您交流! ------------

     泛型通配符?总结

 (1). ?的基本说明

[1].【?使用的场合】

自定义类型参数比较标准的。

但是,如果不想自定义类型参数又想使用泛型,那么就采用?占位符进行类型参数占位

[2]. 【?使用的含义和来历】

因为你也没定义类型参数是什么,所以你也不知道放什么类型。

语义上不知道是什么”就用?来表示。所以泛型也使用?来表示不知道是什么的情况下么也要使用

(2). ?占位符和<>连用时的优势

<?>, <? extends T>或者<? super T>整体跟在原始类型的后面的时候,就能实现<
>中的类型参数存在继承关系
。这个时候,多态就可以应用到含有<?>的类型参数中。

(3). ? 占位符脱离开< >的限制

[1]. 当使用<?>进行类型参数占位的时候,函数体内?相关的代码会有限制

{1}. 从具有<?>限定类型化参数的引用取出元素的时候,元素类型就是?,即元素的类型未知的

MyEclipse验证如下:



可以看出用<?>标记的Iterator<?>的引用it之后, it的方法next()返回值类型是 “?”类型的。

{2}. ?的元素仅仅可以使用Object类型引用进行接收。换句话说只有Object类型的引用可以指向?类型的元素

由于可能是?的元素未知类型的,但是由于是Java中的类型,所以一定是Object类型或者Object的子类。所以使用Object类型的引用可以接收?的元素类型的对象。这是向上转型,javac自动完成。

e.g.



Iterator本身是Iterator<?>的,所以通过其引用it取出来的对象就是?类型的。这里可以看出这样类型的对象可以被Object类型的引用所指向,所以Object obj =it.next()编译通过。

{2}. ?类型的引用或者以?类型的引用为参数的方法不可以指向或者被传入任何类型的对象或者实参

       因为?类型的引用或者参数有两种情况:

i). 如果?类型是Object,这个没问题,可以指向或者被传入任意类型的对象。

ii). 如果?类型不是Object类型,那就是Object的子类,那么你传入的类型未必就是?类型子类,那就不能保证一定是向上转型,很有可能是向下转型。向下转型只能手动进行强制类型转换。所以你直接将其他类型的数据传入到?类型参数或者赋值给?类型引用时候,如果没有强制类型转换,就会出现错误。但是?类型是什么类型又不知道,所以没办法进行强制类型转换。

【结论】所以,不能使用?类型的引用或者以?类型的引用为参数的方法

举例:



可以看出ArrayList<?> al声明的参数化类型引用出来的方法是以?类型的引用为参数的方法。所以和?类型相关的方法是不可以使用的。如果使用,编译报错!!

举例:



(3). <?>和<T>的关系

[1]. <?>和<T>区别

{1}. <?>是真的没有类型。指的是运行期间实际类型参数被<?>接受之后,取出来的变量仍然是?类型的变量。

{2}. <T>是有自己类型的。定义的时候,可以接受任何类型。但是运行期间一旦实际参数传进来,T就被相应的类型取代,不再是未知的类型

[2]. <?>和<T>共性

{1}. <?> <===> <? extends Object>

    <?>就相当于多态中Object的作用,可以接受任何类型的参数

{2}. <T> <===> <T extends Object>

[3]. 练习:

{1}. Class<String> s=Class.forName("java.lang.String"); 编译能通过么?

{1}1. 先看Class.forName()的返回值类型是什么

===> public
static
Class<?>forName(String className)

Class.forName()返回值类型是Class<?> ===>Class<?>是Class参数化类型的Object,相当于最高的父类。

{1}2.将Class<?>类型的对象赋值给Class<String>类型的相当于子类类型的引用,是一种向下类型转换,需要进行手动强制类型转换。这里没有,所以编译不能通过。

MyEclipse验证:



{1}3. 更正办法1:

Class<String>s=(Class<String>) Class.forName("java.lang.String");

{1}4. 更正办法2:

    Class<?> s=Class.forName("java.lang.String");

{2}. 下面一段代码能否通过编译?

Class<?> y;
Class<String>x;
y =x;
x =y;

不能通过编译!!!

y具有参数化类型的最高类型,而Class<String>相当于Class<?>的子类。所以x =y; 相当于向下类型转换,没有强转,编译不能通过。

----------- android培训java培训、java学习型技术博客、期待与您交流! ------------
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐