引入

  • 一个学生的成绩有三种情况

    • 1.整数

    • 2.小数

    • 3.字符串

    如何处理?

不使用泛型:

/**
 * 
 * 获取值
 * 1.强制类型转换
 * 2.手动类型检查:避免转换错误java.lang.ClassCastException
 *
 */
public class Student {

    private Object javase;
    private Object oracle;

    public Student() {

    }

    public Student(Object javase, Object oracle) {
        super();
        this.javase = javase;
        this.oracle = oracle;
    }

    public Object getJavase() {
        return javase;
    }

    public void setJavase(Object javase) {
        this.javase = javase;
    }

    public Object getOracle() {
        return oracle;
    }

    public void setOracle(Object oracle) {
        this.oracle = oracle;
    }

    public static void main(String[] args) {

        //存入整数 int-->Integer-->Object
        Student stu = new Student(80,90);
        //Object-->Integer-->自动拆箱    1.7之后
        int javaseScore = (Integer)stu.getJavase();
        //String oracleScore = (String)stu.getOracle();
        String oracleScore = null;
        if(stu.getOracle() instanceof String){
            oracleScore = (String) stu.getOracle();
        }
        System.out.println("分数为:"+javaseScore+","+oracleScore);
    }
}

泛型的概念

  • 概念:泛型就是参数化类型,使用广泛的类型

  • 起因:数据类型不明确

    • 装入数据的类型都当作Object对待,从而"丢失"自己的实际类型

    • 获取数据时往往需要转型,效率低,容易产生错误

  • 作用:

    • 安全:在编译的时候检查类型安全

    • 省心:所有的强制转换都是自动和隐式的,提高代码的重用率

泛型类

  • 泛型类:定义时使用泛型

    • 格式:<>

    class 类名<字母表>{
    修饰符 字母 属性;
    修饰符 构造器(字母){
    }
    修饰符 返回类型 方法(字母){
    }
    }

  • 泛型常见字母

    T Type 表示类型

    K V 分别代表键值中的Key和Value

    E 代表Element

    ? 表示不确定的类型

不能使用在静态属性,静态方法上

  • 使用:指定具体类型

    • 1.编译时会进行类型检查

    • 2.获取数据时不需要强制类型转换

泛型使用时不能指定基本类型

/**
 * 
 * 泛型只能使用引用类型,不能使用基本类型
 * 泛型声明时不能使用  静态属性或静态方法
 * 因为泛型是在使用时确定的,静态的是在编译时确定的
 */
public class Student<T1,T2> {

    private T1 javaScore;
    private T2 oracleScore;

    public Student() {

    }

    public Student(T1 javaScore, T2 oracleScore) {
        super();
        this.javaScore = javaScore;
        this.oracleScore = oracleScore;
    }

    public T1 getJavaScore() {
        return javaScore;
    }

    public void setJavaScore(T1 javaScore) {
        this.javaScore = javaScore;
    }

    public T2 getOracleScore() {
        return oracleScore;
    }

    public void setOracleScore(T2 oracleScore) {
        this.oracleScore = oracleScore;
    }

    public static void main(String[] args) {

        //使用时指定类型(引用类型)
        Student<String, Integer> stu = new Student<String, Integer>();
        //1.安全:类型检查
        stu.setJavaScore("优秀");
        //2.省心:类型转换
        int it = stu.getOracleScore();//自动拆箱
    }

}

泛型接口

  • 泛型接口:定义接口式使用泛型

    • 1.格式:<>

      interface 接口名 <字母列表>{
      修饰符 返回类型 方法(字母);
      }

    • 2.因为不能使用在静态属性上,更不能使用在全局常量上

demo:

/**
 * 接口中泛型字母只能使用在方法中,不能使用在全局常量中
 */
public interface Comparator<T> {

    void compare(T t);

}

泛型方法

  • 定义使用:<字母>

    修饰符 <字母> 返回类型 方法名(字母){
    }

    要定义泛型方法,只需将泛型参数列表置于返回值前

  • 注意:泛型还可以定义在方法中,是否拥有泛型方法,与其所在的类是否泛型没有关系

import java.io.Closeable;
import java.io.IOException;

/**
 * 只能访问对象的信息,不能修改信息
 **/
public class TestMethoad {

    public static void main(String[] args) {

        test("a");

    }

    public static <T> void test(T a){
        System.out.println(a);
    }

    //extends <=
    public static <T extends Closeable> void test(T... a) throws IOException{
        for (T t : a) {
            if(null!=t){
                t.close();
            }
        }
    }
}