Java日志第32天 2020.8.6

泛型

在前面学习集合时,我们都知道集合中是可以存放任意对象的,只要把对象存储集合后,那么这是他们都会被提升成Object类型,当我们在取出每一个对象,并且进行相应操作,这时必须采用类型转换。

 

看下面的代码:

import java.util.ArrayList;
import java.util.Iterator;

public class Demo01Generic {

    public static void main(String[] args) {
        /*
            创建集合对象,不使用泛型
            好处:集合不使用泛型,默认的就是Object类型,可以存储任意类型的数据
            弊端:不安全,会发生异常
         */
        ArrayList list = new ArrayList();
        list.add(1);
        list.add("aaa");

        Iterator it = list.iterator();

        while(it.hasNext()){
            Object obj = it.next();
            System.out.println(obj);

            /*
                如果需要使用length()方法来返回字符串长度
                由于父类不能直接使用子类方法
                需要使用向下转型
             */
            String s = (String) obj;

            /*
                注意:
                编译器可能会报错
                因为不是所有的数据都是String类型
             */
        }
    }
}

 

 

import java.util.ArrayList;
import java.util.Iterator;

public class Demo01Generic {

    public static void main(String[] args) {
        /*
            创建集合对象,使用泛型
            好处:
                1.避免了类型转换的麻烦,存储的是什么类型,取出的就是什么类型
                2.把运行期异常(代码运行之后会抛出异常),提升到了编译期(写代码的时候回报错)
            弊端:只能存储一种类型的数据
         */
        ArrayList<String> list = new ArrayList();
        list.add(1);//报错
        list.add("aaa");
        list.add("bbb");
        list.add("ccc");

        Iterator<String> it = list.iterator();

        while(it.hasNext()){
            Object obj = it.next();
            System.out.println(obj);
        }
    }
}

 

泛型的定义与使用

当我们不确定要使用什么数据类型时,我们可以使用泛型。

泛型可以接受任意数据类型,Integer, String, Student...

public class GenericClass<E> {
    private E variate;

    public E getVariate() {
        return variate;
    }

    public void setVariate(E variate) {
        this.variate = variate;
    }
}

public class DemoMain {
    public static void main(String[] args) {
        //不使用泛型,默认为Object类型
        GenericClass gc = new GenericClass();
        gc.setVariate("不使用泛型,默认为Object类型");
        Object obj = gc.getVariate();

        //创建GenericClass对象,泛型使用Integer类型
        GenericClass<Integer> gc2 = new GenericClass<>();
        gc2.setVariate(10);
        Integer integer = gc2.getVariate();

        //创建GenericClass对象,泛型使用String类型
        GenericClass<String> gc3= new GenericClass<>();
        gc3.setVariate("String类型");
        String string = gc3.getVariate();

    }
}

 

定义和使用含有泛型的方法

格式:

修饰符 < 泛型 > 返回值类型 方法名称 (参数列表(使用泛型)){

  方法体

}

含有泛型的方法,在调用方法的时候确定泛型的数据类型

传递什么类型的参数,泛型就是什么类型

public class Demo02Main {

    public static void main(String[] args) {
        GenericMethod gm = new GenericMethod();
        gm.method01("abc");
        gm.method01(2.5);
        gm.method01(2);

        System.out.println("===========");
        //调用静态方法
        GenericMethod.method02("abc");
        GenericMethod.method02(2.5);
        GenericMethod.method02(2);

    }
}

 

定义和使用含有泛型的接口

有两种定义泛型接口的方法:

1.定义接口的实现类,实现接口,指定接口的泛型

2.接口和类使用同一种泛型

public class Demo03Main {
    public static void main(String[] args) {
        //创建GenericInterfaceImpl对象
        GenericInterfaceImpl gi = new GenericInterfaceImpl();
        gi.method("String类型");

        //创建GenericInterfaceImpl对象
        GenericInterfaceImpl2<String> gi2 = new GenericInterfaceImpl2<>();
        gi2.method("abc");

        GenericInterfaceImpl2<Integer> gi3 = new GenericInterfaceImpl2<>();
        gi3.method(3);

        GenericInterfaceImpl2<Double> gi4 = new GenericInterfaceImpl2<>();
        gi4.method(8.8);
    }

}

 

泛型通配符

当使用泛型类或者接口是,传递数据中,泛型类型不确定,可以通过通配符<?>表示。但是一旦使用泛型的通配符后,只能用Object类中的共性方法,集合中元素自身方法无法使用。

不知道使用什么类型来接受的时候,此时可以使用?,表示未知通配符。

此时只能接受数据,不能往该集合中存储数据。

 

使用方式:不能创建对象使用,只能作为方法的参数使用

import java.util.ArrayList;
import java.util.Iterator;

public class Demo04Generic {
    public static void main(String[] args) {
        ArrayList<Integer> arr1 = new ArrayList<>();
        arr1.add(1);
        arr1.add(2);
        arr1.add(3);

        ArrayList<String> arr2 = new ArrayList<>();
        arr2.add("aaa");
        arr2.add("bbb");
        arr2.add("ccc");

        printArray(arr1);
        printArray(arr2);
    }

    public static void printArray(ArrayList<?> list){
        Iterator<?> it = list.iterator();
        while(it.hasNext()){
            Object obj = it.next();
            System.out.println(obj);
        }
    }
}

 

泛型的上限限定

? extends E : 代表使用的泛型只能是E类型的子类和本身

泛型的下限限定

? super E : 代表使用的泛型只能是E类型的父类和本身

posted @ 2020-08-06 15:27  Gazikel  阅读(154)  评论(0编辑  收藏  举报