zoukankan      html  css  js  c++  java
  • 泛型(泛型类、方法、通配符、泛型的限定)

    泛型的实质是将数据的类型参数化,在类、接口、方法中定义后,分别被称为:泛型类、泛型接口、泛型方法。泛型类、泛型接口和泛型方法在定义时都是在名字后面加<T>。

    1、泛型类

    public class FanXing<T> {// 定义泛型类,在后面加<T>,T是类型参数
        private T obj;
    
        public T getObj() {//泛型方法
            return obj;
        }
    
        public void setObj(T obj) {
            this.obj = obj;
        }
    
    }
    public class FanXingDemo {
    public static void main(String[] args) {
        FanXing<String>name=new FanXing<String>();//创建泛型类FanXing<T>对象
        FanXing<Integer>age=new FanXing<Integer>();
        name.setObj("Tom");
        age.setObj(21);//自动装箱
        System.out.println(name.getObj());//自动拆箱
        System.out.println(age.getObj());
    }
    }

    在实例化泛型类的过程中,必须使用引用数据类型。与方法的参数不同,泛型的参数可以在方法、类和接口中。

     2、泛型方法

    定义遍历数组的泛型方法:

    package pers.zhb;
    
    public class Way {
    public <E> void show(E[] list){
        for(int i=0;i<list.length;i++){
            System.out.println(list[i]+"  ");
        }
    }
    }

    测试类:

    package pers.zhb;
    
    public class Test {
        public static void main(String[] args) {
    
            Integer[] num = { 1, 23, 465, 12, 0 };
            String[] str = { "xx", "qw" };
            Way way = new Way();
            way.show(num);
            way.show(str);
        }
    
    }

    (3)通配符(?)

    package pers.zhb.fx;
    
    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.HashSet;
    import java.util.Iterator;
    
    public class Fx {
    
        public static void main(String[] args) {
            ArrayList<String> array = new ArrayList<String>();
    
            HashSet<Integer> set = new HashSet<Integer>();
    
            array.add("java");
            array.add("hellow");
    
            set.add(71);
            set.add(20);
    
            iterator(array);
            iterator(set);
        }
        public static void iterator(Collection<?> coll) {
            Iterator<?> it = coll.iterator();//获取集合的实现类对象,病调用集合的iterator()
            while (it.hasNext()) {
                System.out.println(it.next());
            }
        }
    }

    在此方法中<?>通配符的使用,使参数的类型没有任何限制。

    4、泛型的限定:

    定义Animal抽象类:

    package pers.zhb.limit;
    
    abstract class Animal {
        public String food;
        public String colour;
    
        abstract void eat();
    
        abstract void colour();
    
        public Animal(String food, String colour) {
            this.food = food;
            this.colour = colour;
        }
    }

    定义Rabbit、Sheep类,实现Animal接口:

    package pers.zhb.limit;
    
    public class Rabbit extends Animal {
    
        public void eat() {
            System.out.println("小兔子爱吃" + this.food);
    
        }
    
        public void colour() {
    
            System.out.println("小兔子是" + this.colour + "");
        }
    
        public Rabbit(String food, String colour) {
            super(food, colour);
        }
    
    }
    package pers.zhb.limit;
    
    public class Sheep extends Animal{
    
        public Sheep(String food, String colour) {
            super(food, colour);
        }
    
    
        void eat() {
        System.out.println("羊爱吃"+this.food);    
            
        }
    
        void colour() {
        System.out.println("羊的颜色是"+this.colour);
        }
    
    }

    定义测试类:

    package pers.zhb.limit;
    
    import java.util.ArrayList;
    import java.util.Iterator;
    
    public class Test {
        public static void main(String[] args) {
            ArrayList<Rabbit> r = new ArrayList<Rabbit>();
            ArrayList<Sheep> s = new ArrayList<Sheep>();
            Rabbit r1 = new Rabbit("", "白色");
            Rabbit r2 = new Rabbit("胡萝卜", "黑色");
            Rabbit r3 = new Rabbit("白萝卜", "灰色");
    
            r.add(r1);
            r.add(r2);
            r.add(r3);
    
            Sheep s1 = new Sheep("青草", "白色");
            Sheep s2 = new Sheep("树叶", "白色");
    
            s.add(s1);
            s.add(s2);
            Test.showAnimal(r);
            Test.showAnimal(s);//ArrayList<? extends Animal> 对传入的参数进行限定,集合存储的只能是Animal类的对象,或者他的子类对象
        }
    
        public static void showAnimal(ArrayList<? extends Animal> array) {
            Iterator<? extends Animal> it = array.iterator();
            while (it.hasNext()) {
                Animal a = it.next();
                a.eat();
                a.colour();
            }
    
        }
    }

    在这个例子中,如果没有对传入迭代器的参数进行限定,那么传入的数据类型是任意的,对程序的安全性构成威胁。

    上限通配为:?extends T

    下限通配为:?  super T

    5、泛型的好处(转载自博客园:https://www.cnblogs.com/blueGao/p/10220753.html

    (1)提高了程序性能,避免了强制类型转换

    对值类型使用非泛型集合类,在把值类型转换为引用类型,和把引用类型转换为值类型时,需要进行装箱和拆箱操作。装箱和拆箱的操作虽然不需要手动实现,但是性能损失较大。假如使用泛型,就可以避免装箱和拆箱操作。

     ArrayList list=new ArrayList();
     list.Add(20);    //装箱,list存放的是object类型元素,须将值类型转化为引用类型
     int i=(int)list[0];     //拆箱,list[0]的类型是object,要赋值就得把引用类型转化为值类型

    如果换成泛型编程,就不会有装箱和拆箱的性能损失。

     List<T> list=new List<int>();
     list.Add(20);    //因为指定了用int来实例化,因此不必装箱
     int i=list[0];    //同样地,访问时也不需要拆箱

    (2)把运行时期的问题提前到了编译期间 ,提高了代码的安全性

    在定义集合的时候如果不指定泛型可以添加任意类型的数据,安全性是不足的,例如:在定义泛型的时候将泛型定义为Student类型的,那么该集合就只能存储Student类型的集合

    如果使用非泛型编程,如下代码,就有可能在某些情况下会发生异常,因为list数组只要是对象就能存储但是并没有对对象的类型进行限制:

    复制代码
     ArrayList list=new ArrayList();
     list.Add(20);
     list.Add("string");
     list.Add(new MyClass());
     
      foreach(int i in list)
     {
            Console.WriteLine(i);    //这里会有个异常,因为并不是集合中的所有元素都可以转化为int
      }
    复制代码

    如果该用泛型编程,则可以避免这种异常,让编译器检查出错误。

     List<int> list=new List<int>();
     list.Add(20);
     lsit.Add(”string”);   //编译时报错,只能报整数类型添加到集合中
     list.Add(new MyClass());   //同上

    如果按照String类型进行遍历,而集合中还存在int类型的元素,还需要进行向下转型,降低了程序的执行效率。

  • 相关阅读:
    arm-linux-gcc 安装和测试
    JIT动态编译器的原理与实现之Interpreter3
    sql server常有的问题-实时错误'91' 对象变量或with块变量未设置
    WM_PARENTNOTIFY的作用(不完全)
    WM_CLOSE、WM_DESTROY、WM_QUIT学习总结(点击关闭按钮会触发WM_CLOSE消息,DestroyWindow API会触发WM_DESTROY和WM_NCDESTROY消息,MSDN上写的很清楚)
    Windows XP 每次开机都自动检测硬盘 解决办法(可以用HDDRegenerate修复坏道)
    这141家创业公司为什么失败
    QTableView 固定列宽度(鼠标拖动后,仍可固定)
    银行快捷支付的思考
    QQ空间如何显示相片
  • 原文地址:https://www.cnblogs.com/zhai1997/p/11360785.html
Copyright © 2011-2022 走看看