zoukankan      html  css  js  c++  java
  • 泛型总结

    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类型的父类对象赋值。 * * */

  • 相关阅读:
    添加了tabBar之后就不能使用wx.navigateTo跳转页面
    nodejs的安装及创建项目
    人名币转大写
    C#后台去除HTML标签
    自动化测试中excel的使用
    ddt方法介绍
    requests返回值
    requests提供的get方法,有几个常用的参数
    serveragent组件含义
    jmeter使用PerfMon Metrics Collector的图表分析
  • 原文地址:https://www.cnblogs.com/hujingwei/p/5147407.html
Copyright © 2011-2022 走看看