黑马程序员技术交流社区
标题: 我对泛型类的理解,思路可能和书上不一样 [打印本页]
作者: 至尊幽蓝 时间: 2015-8-31 13:13
标题: 我对泛型类的理解,思路可能和书上不一样
本帖最后由 至尊幽蓝 于 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的子类。
作者: 至尊幽蓝 时间: 2015-8-31 13:36
本帖最后由 至尊幽蓝 于 2015-8-31 23:32 编辑
最后一个例子,忘了Collectin是接口了,应该用一个可实例化的集合。
作者: 至尊幽蓝 时间: 2015-8-31 20:48
沉的好快
作者: 夕阳游子 时间: 2015-8-31 21:01
感谢楼主分享
作者: 至尊幽蓝 时间: 2015-8-31 23:39
内容又更新了
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) |
黑马程序员IT技术论坛 X3.2 |