泛型

一、使用泛型的好处

   创建集合对象,不使用泛型

  好处:集合不使用泛型,默认是Object类型,可以存储任意的数据类型
  弊端:不安全,会抛出异常

创建集合对象,使用泛型
  好处:避免了类型转化的麻烦,存储的是什么类型,取出的就是什么类型
将运行时期的异常提到了编译时期
弊端:泛型是什么类型,就只能存储什么类型的数据
import java.util.ArrayList;
import java.util.Iterator;

public class Demo01Generic {
    public static void main(String[] args) {
        show01();
        System.out.println("===========");
        show02();

    }

    private static void show02() {
        //使用泛型
        ArrayList<String> list = new ArrayList<String>();
        list.add("123");
        list.add("ABC");
//        list.add(1);    //只能存储字符串类型的数据
        for (String str : list){
            System.out.println("字符串:"+str+",长度:"+str.length());
        }
    }

    private static void show01() {
        //不使用泛型
        ArrayList list = new ArrayList();
        list.add("abc");
        list.add(1);
        //获取迭代器
        Iterator it = list.iterator();
        while(it.hasNext()){
            Object obj = it.next();
            System.out.println(obj);
            //获取集合的长度,需要类型的转换
            //注意:抛出异常:Integer cannot be cast to java.lang.String
            /*String str = (String)obj;
            System.out.println("集合的长度:"+str.length());*/
        }
    }
}

二、泛型的定义与使用

1.定义和使用含有泛型的类

GenericClass类

public class GenericClass<E> {
    private E name;

    public E getName() {
        return name;
    }

    public void setName(E name) {
        this.name = name;
    }
}
Demo02GenericClass类
/*
泛型:数据类型未知
 */
public class Demo02GenericClass {
    public static void main(String[] args) {
        //创建字符串类型的对象
        GenericClass<String> gc = new GenericClass<String>();
        gc.setName("小明");
        String name = gc.getName();
        System.out.println("姓名1:"+name);
        //创建整型对象
        GenericClass<Integer> gc2 = new GenericClass<Integer>();
        gc2.setName(1);
        Integer name1 = gc2.getName();
        System.out.println("姓名2:"+name1);
    }
}

2.含有泛型的方法

使用泛型来定义方法:
注意:泛型写在访问符和返回值的类型之间
在调用方法时确定泛型的具体数据类型
GenericMethod类
public class GenericMethod {
    //定义一个带有泛型的方法
    public <E> void method01(E e){
        System.out.println(e);
    }
    //定义一个带有泛型的静态方法
    public static <M> void method02(M m){
        System.out.println(m);
    }
}
Demo03GenericMethod类
public class Demo03GenericMethod {
    public static void main(String[] args) {
        //普通成员方法调用
        GenericMethod gm = new GenericMethod();
        gm.method01("(1)你好,中国!");
        gm.method01("(2)"+1314520);
        gm.method01("(3)"+3.14);
        System.out.println("========================");
        //静态方法调用
        GenericMethod.method02("(4)中国我爱你");
        GenericMethod.method02("(5)"+1314520);
        GenericMethod.method02("(6)"+3.14);
    }
}

3.含有泛型的接口

含有泛型的接口,第一种使用方式:定义接口的实现类,实现接口,指定接口的类型
public interface Iterator<E>{
E next();
}
Scanner类实现了Iterator接口,并指定接口的泛型为String,所以重写的next方法泛型默认是String
public final class Scanner implements Iterator<String>{
public String next(){}
}
含有泛型的接口,第二种使用方式:接口使用什么类型,实现类就使用什么类型,类跟着接口走
相当于定义了一个还有泛型的类,创建对象时确定泛型的类型
public interface List<E>{
boolean add(E e);
E get(int index);
}
public class ArrayList<E> implements List<E>{
public boolean add(E e){}
public E get(int index){}
}
GenericInterface 接口
public interface GenericInterface<E>{
    public void method(E e);
}
GenericInterfaceImpl1 实现类
public class GenericInterfaceImpl1 implements GenericInterface<String> {
    public void method(String s) {
        System.out.println(s);

    }
}
GenericInterfaceImpl2 实现类
public class GenericInterfaceImpl2<I> implements GenericInterface<I> {
    public void method(I i) {
        System.out.println(i);
    }
}
Demo04GenericInterface 测试类
public class Demo04GenericInterface {
    public static void main(String[] args) {
        //创建GenericInterfaceImpl1对象
        GenericInterfaceImpl1 gci = new GenericInterfaceImpl1();
        gci.method("你好呀!");
        System.out.println("==========================");
        //创建GenericInterfaceImpl2对象
        GenericInterfaceImpl2<String> gci2 = new GenericInterfaceImpl2<String>();
        gci.method("Hello!");
        GenericInterfaceImpl2<Double> gci3 = new GenericInterfaceImpl2<Double>();
        gci3.method(3.14);
    }
}

三、泛型通配符

1.通配符的基本使用

泛型的通配符:
?:代表任意的数据类型
使用方式:
不能创建对象使用
只能作为方法的参数使用

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

public
class Demo05Generic { public static void main(String[] args) { ArrayList<Integer> list01 = new ArrayList<Integer>(); list01.add(1); list01.add(2); ArrayList<String> list02 = new ArrayList<String>(); list02.add("你好"); list02.add("我很好"); printArray(list01); printArray(list02); } /* 定义一个方法,可以遍历所有类型的ArrayList集合 可以使用通配符 */ public static void printArray(ArrayList<?> list){ //获取迭代器 Iterator<?> it = list.iterator(); while (it.hasNext()){ Object obj = it.next(); System.out.println(obj); } } }

2.通配符的高级使用------受限泛型

泛型的高级使用
泛型的上限限定:? extends E 代表使用的泛型只能是E类型的子类或本身
泛型的下限限定:? super E 代表使用的泛型只能是E类型的父类或本身

import java.util.ArrayList;
import java.util.Collection;


public
class Demo06Generic { public static void main(String[] args) { Collection<Integer> list1 = new ArrayList<Integer>(); Collection<String> list2 = new ArrayList<String>(); Collection<Number> list3 = new ArrayList<Number>(); Collection<Object> list4 = new ArrayList<Object>(); /* 类与类之间的继承关系 Integer extends Number extends Object String extends Object */ getElement1(list1); // getElement1(list2); //报错 getElement1(list3); // getElement1(list4); //报错 // getElement2(list1); //报错 // getElement2(list2); //报错 getElement2(list3); getElement2(list4); } //泛型的上限:此时的类型?必须是Number类型或Number类型的子类 public static void getElement1(Collection<? extends Number> coll){}; //泛型的下限:此时的类型?必须是Number类型或Number类型的父类 public static void getElement2(Collection<? super Number> coll){}; }


 


原文地址:https://www.cnblogs.com/my-program-life/p/11623082.html