泛型总结

import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
 
//为什么要使用泛型
class Student{
     private  int studentnum;
     public Student(int number){
         studentnum=number;
      }
     public String toString(){
         return " "+this.studentnum; 
      }
 }
public class GenericMethodDemo1{
     public static void main(String[] args){
     Vector v=new Vector();
     Student s1=new Student(1);
     Student s2=new Student(2);
     Student s3=new Student(3);
     Student s4=new Student(4);
     Student s5=new Student(5);
     Student s6=new Student(6);
     Integer t=new Integer(10);
     v.add(s1);
     v.add(s2);
     v.add(s3);
     v.add(s4);
     v.add(s5);
     v.add(s6);
     v.add(t);
     for(int i=0;i<v.size();i++){
        Student s=(Student) v.get(i);
        System.out.print(s.toString()+" ");
     }
   }
}
/*(1)上述代码虽然编译通过,但是运行时却出现了异常————ClassCastException。这主要是遍历集合对象v的最后
 * 一个对象时,由于该对象t是一个Integer对象而不是Student对象,所以在运行Student s=(Student) v.get(i);
 * 代码时会出错。
 * (2)对于上述代码存在安全隐患,即强制转换类型时会出现错误,编译器是不会提示出现错误的,但是在运行时却会
 * 出现异常。因此需要使用泛型,用来限制向对象集合中添加对象的类型,如果添加的类型不是指定的泛型类型,就会出现
 * 编译时错误。例:Vector<Student> v=new Vector();这句代码限制了集合v中的对象只能是Student对象
 * */
*******************************************************************************************************************************
泛型的一些特性
 * 1.参数化类型与原始类型的兼容
 *   也就是说指定的泛型类型可以放在等号左边也可以放在等号右边(编译器只会警告,但是不会报错)
 *   例:
 *      Vector<String> v=new Vector();
 *      Vector v=new Vector<String>();
 * 2.参数化类型无继承性
 *      Vector<String> v=new Vector();
 *      Vector<Object> v1=v;
 *      有些程序员认为由于String类型是Object类型的子类,所以String类型的Vector对象v可以赋值给Object类型的
 *      Vector对象v1。
 *      v1.add(new Object());
 *      String s=v.get(0);
 *      在上述代码中,首先v1对象中添加一个Object类型对象成员,接着由于v1与v都指向同一个对象,所以可以通过v对象
 *      获取添加到v1对象中的成员。这时就会出现错误,因为v对象中的成员不再是String类型。所以代码Vector<Object> v1=v;
 *      是错误的。
 * 3.泛型的“去类型”的特性
 *    所谓“去类型”,就是指泛型中的类型只是提供给编译器使用,当程序编译成功后就会去掉“类型”信息。如下面的代码:
import java.util.ArrayList;
public class GenericMethodDemo2 {
        public static void main(String[] args) {
                 ArrayList<String> array1=new ArrayList<String>();
                 array1.add("hujingwei");
                 ArrayList<Integer> array2=new ArrayList<Integer>();
                 array2.add(20);
               System.out.println("array1与array2是否指向同一份字节码?"+(array1.getClass()==array2.getClass()));
          }
}
 * 
 * 
 * 4.利用反射绕过泛型的类型限制
 *    由于编译器生成的字节码去掉泛型的类型信息,所以只要跳过编译器,还是可以给通过泛型限制的类型集合加入
 *    其他数据类型。如下面的代码:
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
public class GenericMethodDemo3 {
    public static void main(String[] args) throws IllegalArgumentException, SecurityException, IllegalAccessException, InvocationTargetException, 
NoSuchMethodException { ArrayList
<Integer> array1=new ArrayList<Integer>(); array1.add(12); array1.add(34); array1.getClass().getMethod("add", Object.class).invoke(array1, "abc"); System.out.println("第一个元素为:"+array1.get(0)); System.out.println("第二个元素为:"+array1.get(1)); System.out.println("第三个元素为:"+array1.get(2)); } } import java.util.Vector; 泛型通配符 //<?>类型的通配符 public class GenericMethodDemo4 { public static void main(String[] args) { Vector<Integer> v=new Vector<Integer>(); v.add(2); v.add(5); Vector<Object> v1=new Vector<Object>(); v1.add("aa"); v1.add(2.3); randomMeth(v); randomMeth(v1); } private static void randomMeth(Vector<?> vector) { System.out.println("输出"+vector+"各个成员-------------"); for(Object obj:vector){ System.out.println(obj); } System.out.println("对象的大小"+vector.size()); } } /*在randomMeth方法中,通过?标识实现接受任何类型参数的方法,即在具体调用具体方法时,传入的对象 * 可以是任意类型。虽然可以接受任意类型,但是具体接受什么类型只是在具体调用该方法时才能确定。因此在 * 该方法中添加类型成员vector.add("1");时,就会出现编译错误。可是如果调用与参数无关的方法时vector.size(), * 则不会报错。 * */ import java.util.ArrayList; import java.util.List; //<? extends U> <? super U> public class GenericMethodDemo5 { public static void main(String[] args) { Number num1=new Integer(1); Number num2=new Double(1.23); List<Number> listNums=new ArrayList<Number>(); listNums.add(1); listNums.add(1.23); List<Integer> listInteger=new ArrayList<Integer>(); List<Number> listNums1=new ArrayList<Number>(); List<? extends Number> listNums2=listInteger; List<? super Integer> listNums3=listInteger; listNums3.add(7); listNums3.add(null); } } /*对象num1和num2的定义代码,子类(Integer,Double)可以自动转换成其父类(Number)。同理,ArrayList<Number> * 泛型也可以自动转换成List<Number>泛型,因为List是ArrayList类的父类。 * List<Integer>类型的对象listInteger,之所以不能赋给List<Number>类型的对象listNums1,是因为泛型参数类型无 * 继承性。因此,虽然Integer是Number的子类,但是充当放行参数时,则不能实现转换。 * 为了解决泛型参数类型无继承性,出现了extends和super标识符。List<? extends Number> listNums2;表示该对象可以被 *Number类型的任何子类对象(List<Integer>)赋值。List<? super Integer>表示该对象可以被Integer类型的父类对象赋值。 * * */

 


转载于:https://www.cnblogs.com/hujingwei/p/5147407.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值