文章目录

  • 引 -对于传统方法的问题分析
  • 泛型介绍
  • 泛型语法
  • 自定义泛型
  • 自定义泛型类
  • 自定义泛型接口
  • 自定义泛型方法
  • 泛型的继承和通配符


引 -对于传统方法的问题分析

  • 不能对加入集合 ArrayList 中的数据进行约束(不安全)
  • 遍历的时候,需要进行类型转换,如果集合中的数据量较大,对效率有影响

泛型介绍

  • 泛型又称参数化类型,是jdk5.0出现的新特性,解决数据类型的安全问题
  • 在类声明或实例化时只要指定好需要的具体的类型即可
  • Java 泛型可以保证如果程序在编译时没有发出警告,运行时就不会产生 ClassCastException 异常,同时,代码更加简洁、健壮
  • 泛型的作用是:可以在类声明时通过一个标识表示类中某个属性的类型,或者是某个方法的返回值的类型,或者是参数类型。
class Person<E> {
    E e;    //E表示 e的数据类型,该数据类型在定义Person对象的时候
            // 指出,即在编译期间,就确定E是什么类型

    public Person(E e){ //E也可以是参数类型
        this.e = e;
    }

    public E f(){   //返回类型使用E
        return e;
    }
}

泛型语法

  • 泛型的声明
  • interface 接口{} 和 class 类<K,V>{}(比如:List,ArrayList)

说明

  1. 其中,T,K,V不代表值,而是表示类型
  2. 任意字母都可以。常用 T 表示,是 Type 的缩写
  • 泛型的实例化
List<String> strList = new ArrayList<>();
 Iterator<Customer> iterator = customers.iterator();
  • 使用的注意事项和细节
  1. interface List{},public class HashSet{}… 等等
    说明:T,E只能是引用类型,不能是基本数据类型
    错误示例
List<int> list = new ArrayList<int>();
  1. 在给泛型指定具体类型后,可以传入该类型或者其子类型
  2. 泛型的使用形式
ArrayList<Integer> list1 = new ArrayList<Integer>();
List<Integer> list2 = new ArrayList<Integer>();
//在实际开发中,往往简写
List<Integer> list3 = new ArrayList<>();
ArrayList<Integer> list4 = new ArrayList<>();
  1. 如果是这样写,泛型默认为Object
ArrayList list = new ArrayList();//相当于ArrayList<Object> list = new ArrayList<>();

自定义泛型

自定义泛型类

  • 基本语法
class 类名<T,R...> {//...表示可以有多个泛型、
    成员
}
  • 注意细节
  1. 普通成员可以使用泛型(属性、方法)
  2. 使用泛型的数组,不能初始化
  3. 静态方法中不能使用类的泛型
  4. 泛型类的类型,是在创建对象时确定的(因为创建对象时,需要指定确定类型)
  5. 如果在创建对象时,没有指定类型,默认为Object

自定义泛型接口

  • 基本语法
interface 接口名<T,R...>{
}
  • 注意细节
  1. 接口中,静态成员也不能使用泛型(这个和泛型类规定一样)
  2. 泛型接口的类型,在继承接口或者实现接口时确定
  3. 没有指定类型,默认为Object

自定义泛型方法

  • 基本语法
修饰符<T,R>返回类型 方法名(参数列表){
}
  • 注意细节
  1. 泛型方法,可以定义在普通类中,也可以定义在泛型类中
class Car {//普通类
    public void run() {

    }
    //说明 泛型方法
    //1. <T,R>就是泛型
    //2. 是提供给fly使用的
    public <T,R> void fly(T t,R r) {

    }
}

class Fish<T,R> {
    public void run() {//普通方法
    }
    public<U,M> void eat(U u, M m){//泛型方法
    }
}
  1. 当泛型方法被调用时,类型会确定
  2. public void ear(E, e){},修饰符后没有<T, R> eat方法不是泛型方法,而是使用了泛型

泛型的继承和通配符

  • 泛型不具备继承性
  • <?>:支持任意泛型类型
  • <? extends A>:支持A类以及A类的子类,规定了泛型的上限
  • <? super A>:支持A类以及A类的子类,不限于直接父类,规定了泛型的下限