泛型

泛型语法

泛型可以在编译的时候检查元素的类型,提高安全型;减少类型转换次数,提高效率

List<Dog> dogs = new ArrayList<>();
dogs.add(new Dog("小黄",1));
dogs.add(new Dog("小花",2));
dogs.add(new Dog("小红",2));

//遍历
for(Dog dog: dogs){
    System.out.println(dog.getName() + "," + dog.getAge());
}
  1. 泛型又称为参数化类型,在JDK5.0中出现,解决数据类型中的安全性问题。
  2. 在类声明或者实例化的时候指定需要的具体类型即可
  3. Java泛型保证了在编译时没有发生警告,在运行时就不会发生类型转换异常的错误,同时代码更简洁、健壮
  4. 泛型的作用:可以在类声明的时候通过一个标识标识类中某个属性的类型,或者某个方法的返回类型或者参数类型。
public class Generic2 {
    public static void main(String[] args) {
        Person<String> person = new Person<String>("hello");
    }
}
//在类定义的时候指定类型
class Person<T>{
    //泛型类型的属性
    T s;
	//用泛型作为参数类型
    public Person(T s) {
        this.s = s;
    }
	//返回泛型
    public T getS() {
        return s;
    }

    public void setS(T s) {
        this.s = s;
    }
}

泛型的声明:
interface 接口{}
class 类<K,V>{}
其中T,K,V不代表值,代表类型

泛型实例化:
例如:
List list = new ArrayList();

细节

  1. 泛型只能是引用类型

  2. 给定泛型的具体类型以后,可以传入泛型的类型或者子类型

  3. 泛型的使用形式:

    ArrayList<String> list = new ArrayList<String>();
    
    ArrayList<String> list = new ArrayList<>();//推荐这种写法
    
  4. 没有指定泛型,泛型默认就是Object

自定义泛型

  1. 普通成员可以使用泛型(属性和方法)
  2. 使用泛型的数组,不能初始化
  3. 静态方法中不能使用类的泛型
  4. 泛型类的泛型,会在创建对象的时候确定
  5. 如果在创建对象的时候没有指定泛型,默认就是Object
class Tiger<T,R,E>{
    private String name;
    private T t;
    private R r;
    private E e;//使用泛型定义属性
    private T[] ts;//泛型数组不能初始化,泛型没有确定,不知道开辟多少内存空间 
    
     //不能使用泛型修饰静态属性和在静态方法中使用属性,静态属性随着类的加载而加载,泛型没有确定
     //public static T t1;
//     public static void m1(){
//         System.out.println(t);
//     }
     public Tiger(String name, T t, R r, E e) {//在构造器中使用泛型
         this.name = name;
         this.t = t;
         this.r = r;
         this.e = e;
     }
        
     public T getT() {//在方法中使用泛型作为返回值
         return t;
     }

     public void setT(T t) {//在方法中使用泛型作为形参类型
         this.t = t;
     }
 }

自定义泛型接口

interface 接口名<泛型>{}

  1. 在接口中静态成员不能使用泛型
  2. 泛型接口的类型,在继承接口或者实现接口中确定
  3. 没有指定类型默认就是Object

自定义泛型方法

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

1.泛型方法即可以定义在普通类中,也可以定义在泛型类中

2.当泛型方法被调用的时候,泛型就会被确定

3.public void eat(T t){},这个方法不是泛型方法,只是使用了泛型,修饰符后面没有

//普通类
class A{
    //定义泛型方法,K,T是泛型
    public <T,K> void eat(T t,K k){
        System.out.println(t.getClass());
        System.out.println(k.getClass());
    }
}
class B<T>{
    //定义泛型方法
    public <E> void eat(T t,E e){
        System.out.println(t.getClass());
        System.out.println(e.getClass());
    }
}

泛型的继承和通配符

  1. 泛型不具备继承性

    List<Object> list = new ArrayList<String>();这句语句是错误的,泛型不存在继承性

  2. 支持任意泛型类型
  3. 支持A类及A类的子类,规定了上限
  4. 支持A类以及A类的父类,不限于直接父类,规定了下限
public class Generic6 {
    public static void main(String[] args) {
        List<Object> list1 = new ArrayList<>();
        List<String> list2 = new ArrayList<>();
        List<AA> list3 = new ArrayList<>();
        List<BB> list4 = new ArrayList<>();
        List<CC> list5 = new ArrayList<>();
        
        //List<?> list 支持任意类型泛型
        printCollection1(list1);
        printCollection1(list2);
        printCollection1(list3);
        printCollection1(list4);
        printCollection1(list5);
        
        //List<? extends AA> list 支持AA及AA的子类型泛型
        printCollection2(list3);
        printCollection2(list4);
        printCollection2(list5);
        
        //List<? super AA> list 支持AA和AA的父类型泛型
        printCollection3(list1);
        printCollection3(list3);
        
    }
    public static void printCollection1(List<?> list){
        for (Object o : list) {
            System.out.println(o);
        }
    }
    
    public static void printCollection2(List<? extends AA> list){
        for (AA aa : list) {
            System.out.println(aa);
        }
    }
    
    public static void printCollection3(List<? super AA> list){
        for (Object o : list) {
            System.out.println(o);
        }
    }
}
class AA{}
class BB extends AA{}
class CC extends BB{}
posted @ 2021-10-05 15:11  无涯子wyz  阅读(37)  评论(0)    收藏  举报