本帖最后由 至尊幽蓝 于 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的子类。
|