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类型的元素,还需要进行向下转型,降低了程序的执行效率。

  • 相关阅读:
    JavaScript操作符instanceof揭秘
    Linux打开txt文件乱码的解决方法
    Working copy locked run svn cleanup not work
    poj 2299 UltraQuickSort 归并排序求解逆序对
    poj 2312 Battle City 优先队列+bfs 或 记忆化广搜
    poj2352 stars 树状数组
    poj 2286 The Rotation Game 迭代加深
    hdu 1800 Flying to the Mars
    poj 3038 Children of the Candy Corn bfs dfs
    hdu 1983 Kaitou Kid The Phantom Thief (2) DFS + BFS
  • 原文地址:https://www.cnblogs.com/zhai1997/p/11360785.html
Copyright © 2011-2022 走看看