黑马程序员--04.泛型深入--02【参数化类型的特点】

泛型深入--2

参数化类型的特点

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

 参数化类型的特点

1). 类型化不具有继承性

参数化类型不考虑< >传入的具体化的类型参数之间是否存在继承性。

【例子1】Vector<String> v =new Vector<Object>();//X


【例子2】Vector<Object> v =new Vector<String>();//X


【误区】尽管参数化类型Vector<String>中的元素类型是String,左边的参数化类型Vector<Object>中的元素是Object。

单单从集合中元素类型上来看,String类型的对象是可以被父类类型的引用Object指向的。但是,在参数化类型整体的Vector<String>中的< >具体类型是不可以考虑继承关系的。

泛型中规定:没有通配符?的情况下,Vector<String>的集合中的元素只能存放String类型的数据,不是String类型的数据坚决不能存放。同理,Vector<Object>的集合中的元素也只能存Object类型的数据,也不能存放其他类型的数据

【例子3】下面的代码能通过编译么?

Vector v1 =new Vector<String>();

Vector<Object> v2 =v1;

答:可以通过。

{1}. 编译器特点

{1}1. 编译器是一个严格按照语法进行检查的工具

{1}2. 编译器仅仅按照行进行代码检查不考虑行与行之间语法检查的关系,仅仅按照行进行语法翻译

【考虑行与行之间运行结果之间的关系运行时期关心的事情,是JVM的事情】

{2}. 分析题目

{2}1.对Vector v1 =newVector<String>();  javac进行语法检查

由于语法上规定原始类型和参数化类型是双向兼容的,所以编译通过。

{2}2.对Vector<Object> v2 =v1;    javac进行语法检查

v1的类型是原始数据类型,v2是参数化数据类型,仍然符合双向引用的原则,所以编译仍然通过。

【采用MyEclipse进行验证】


【理解误区】

X X X X X

看成参数传递过程:

Vector v1 =new Vector<String>();

Vector<Object> v2 =v1;

由于v1是中间变量, 所以以上就可以写成Vector<Object> v2 =newVector<String>(); 违反了具体的类型参数是不考虑继承特性的原理。所以认为javac报错。

X X X X X

2). 数组、类型参数和参数化类型

(1). 数组和类型参数的关系

[1]. 泛型数组引用

{1}.泛型数组引用:

当在< >中定义的类型参数作为类型单独使用并且放在数组标示[ ]前的时候,这个被类型参数声明数组引用称为泛型数组引用

{2}. 泛型数组引用的应用场景

可以方法参数列表定义泛型数组引用作为参数列表的一部分。

示例代码:

public class Test<T> {
    public void method(T [] arrGeneric){
       System.out.println(arrGeneric.length);
       for(T t: arrGeneric){
           System.out.print(t+" ");
       }
    }
      
    public static void main(String[] args) {
       Test<String>tString =new Test<String>();
       String[]strArr =new String[]{"ABC","DEF", "GHI"};
       tString.method(strArr);
    }
}

打印结果:


[2]. 类型参数绝对不能出现在new关键字之后用来定义泛型数组!!!!!

【原因】但是编译的时候编译器要求数组new后面必须明确数组元素的类型。使用类型参数是不知道数组元素具体是什么类型,所以会报错。

错误示例:


(2). 数组和参数化类型的关系

[1]. 参数化类型不可以出现new数组标示 [ ] 之间。

也就是不能创建以参数化类型为元素类型数组

【错误示例】


[2]. 参数化类型引用

建立参数化类型引用作为函数的参数或者直接作为引用变量是可以的。

【正确示例1】直接作为引用变量存在


【正确示例2】作为函数的参数

public class TestI<T> {
    public void method(Collection<String>[] collArrGeneric){
       System.out.println(collArrGeneric.length);
       for(Collection<String> coll:collArrGeneric){
           System.out.println("******");
           for(String s: coll){
              System.out.print(s +" ");
           }
           System.out.println();
       }
    }
        
    public static void main(String[] args) {
       TestI<String>tString =new TestI<String>();
       Collection<String>[]collArrGeneric =new ArrayList[2];
      
       collArrGeneric[0]=new ArrayList<String>();
       collArrGeneric[0].add("ABC1");
       collArrGeneric[0].add("DEF1");
       collArrGeneric[0].add("GHI1");
      
       collArrGeneric[1]=new ArrayList<String>();
       collArrGeneric[1].add("ABC2");
       collArrGeneric[1].add("DEF2");
       collArrGeneric[1].add("GHI2");
      
       tString.method(collArrGeneric);
    }
}

打印结果:


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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值