A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 至尊幽蓝 于 2015-8-31 23:30 编辑

      下面是我对泛型类的理解,思考的角度可能和书本上的有些不同,但很坚定。
      自Java1.5版本泛型出现,集合类应该是被重新书写了,由普通类改写成了泛型类。
泛型类的使用过程包括的步骤有:泛型类引用的声明,泛型类对象的创建以及引用指向对象。作此说明是为了下面方便说明我对泛型的理解。

1.声明泛型类引用时,需在类名后指出泛型指代的类型,注意我说的是指出,不是指明。这里指出的意思是有<…>这组符号,放个”?”或”?extends(super) XXX”也算指出了。如果不指出,也可以编译运行,并且未做出指出的泛型可以指代任意类型,但会有警告。集合类(泛型版本)就表现出这个特性了。
举例:(String只是举例)
MyClass<String> mc;    //可编译运行,无警告,mc中相应的泛型只能使用String
MyClass     mc;         //可编译运行,有警告,mc中相应的泛型可以指代任意类型

2.创建泛型类对象时,需要在类名后指明泛型指代的类型,注意这里我说的是指明,”?”或”? extends(super) XXX”不算指明。就是有<String>,尖括号中的泛型必须具体到某一种类型。如果不指出也会有警告,但同样也能编译运行,并且未指出的泛型可以指代任意类型,但如果指出了却未指明,即”?”或”? extends(super) XXX”,就不是警告了,而是错误。
举例:(String只是举例)
new MyClass<String>();     //可编译运行,无警告,其中相应的泛型只能使用String
new MyClass();     //可编译运行,有警告,其中相应的泛型可以指代任意类型
new       MyClass<?>();             //错误。

3.泛型引用指向泛型对象,
      1)未指出泛型类型的引用,可以指向泛型类型被指明为任意类型的泛型对象,即“MyClass mc; ” 声明的mc可以指向new MyClass()   ,new MyClass< XXX>(),  XXX可以为具体到某一种类型的任意类型。
      2)MyClass<String> mc; 声明的mc只能指向new MyClass(),new MyClass< String >(),
在这里,new MyClass() 被自动转换成了String,此转换是未经检查的,
当new MyClass()不是String类型时,一旦调用mc的String方法时,就会抛出转换异常。
      3) MyClass<?> mc;  中的mc可以指向的泛型类和“MyClass mc; ”中的mc可以指向的类型一样,只是这样声明不会出现警告。
      4)MyClass<? extends  Father> mc; 声明的mc可以指向new MyClass() 和new  MyClass<XXX >(),  XXX是Father及其子类中具体到某一种的类。
在这里,new MyClass()被自动转换成了Father(eclipse中写的是转换成“? extends  Father”,但给出的方法只是Father的方法。此转换是未经检查的,
当new MyClass()不是Father类型时,一旦调用mc的Father方法时,就会抛出转换异常。
      5)MyClass<? super Father>  mc;  同4)相似,只是XXX是Father及其父类。

      关于引用指向对象:
1)MyClass<? extends  Father> mc =new MyClass<Son>();   是mc指向了后面创建的对象;
2)另一种情况,定义方法:
Void  show(MyClass<?  extends Father>   mc){}   这里也是声明了一个引用,当使用该方法时,就是让这个引用指向了相应的对象,所以在使用该方法时,其中的参数mc只能是上面4)所包括的类型。
举例:
ArrayList的一个构造方法的定义:ArrayList(Collection<? extends Father>  c){…}  该构造方法用到的Father是定义ArrayList<E>时其中的E。
下面是该方法的使用即调用该构造方法创建一个ArrayList:
Student和Worker均是Person的子类:
1                ArrayList<Student> slis=new ArrayList<Student>();
2                LinkedList<Worker> wlis=new LinkedList<Worker>();
3                ArrayList<Person> plis1=new ArrayList<Person>(slis);
4                ArrayList<Person> plis2=new ArrayList<Person>(wlis);
5                ArrayList<String> ms=new ArrayList<String>();                                        //String不是Person的子类
6//                ArrayList<Person> plis3=new ArrayList<Person>(ms);               
7                LinkedList<Object> mo=new LinkedList<Object>();                                //Object是Person的父类,但此处要子类
8//                ArrayList<Person> plis4=new ArrayList<Person>(mo);
第3行和第4行定义ArrayList时,用了上面的构造方法,其中的E是Person,所以括号中的Collection<...>中的泛型必须是Person或其子类,正如第1行和第2行定义的,slis中的Student和wlis中的Worker都是Person的子类,所以第3和第4行没问题;但是第6行和第8行会出错,因为String和Object都不是Person的子类。



5 个回复

倒序浏览
本帖最后由 至尊幽蓝 于 2015-8-31 23:32 编辑

最后一个例子,忘了Collectin是接口了,应该用一个可实例化的集合。

点评

改过来了,怎么删除回复啊  发表于 2015-8-31 23:32
回复 使用道具 举报
沉的好快
回复 使用道具 举报
感谢楼主分享
回复 使用道具 举报

内容又更新了
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马