java基础 --泛型

目录

27、泛型

1、概念

2、泛型的语法

3.使用细节

自定义泛型类

自定义泛型接口

自定义泛型方法

4.泛型的继承和通配符


27、泛型

在没引入泛型之前,传统方法有以下几个问题

  1. 不能对加入到集合中的数据类型进行约束(不安全)

  2. 遍历的时候,需要进行类型转换,如果集合中的数据量很大,对效率有影响

如果使用泛型

import java.util.ArrayList;
import java.util.List;
​
/**
 * @author: wentao
 * @date: 2022/11/2 17:11
 * @version: 1.0
 * @description: 泛型体验
 */
public class Generic_ {
    public static void main(String[]args){
        /*
           1.如果编译器发现添加的类型,不符合要求 ,就会报错
           2. 在遍历的时候,可以直接取出Integer类型而不是Object
         */
        List<Integer>  list  = new ArrayList();
        list.add(1);
        list.add(12);
        list.add(13);
        //假如不小心输错数据了 添加了一个String类型
        //编译器会进行检查
//        list.add("tom"); 
        for (Integer integer : list) {
            System.out.println(integer);
        }
    }
}
 

1、概念

  1. 泛型又称为参数化类型,是jdk5出现的新特性,解决数据类型的安全性问题

  2. 在类声明或实例化时,只要指定好需要的具体类型即可

  3. java泛型可以保证如果程序在编译时没有发出警告,运行的时候就不会产生ClassCastException异常,同时,代码更加简洁、健壮

  4. 泛型的作用:可以在类声明时通过一个标识表示 类中某个属性的类型,或者是某个方法的返回值类型,或者是参数类型

import java.util.ArrayList;
import java.util.List;
​
/**
 * @author: wentao
 * @date: 2022/11/2 19:26
 * @version: 1.0
 */
public class Generic2 {
    public static void main(String[]args){
        Person1 p =  new Person1("String");
        System.out.println(p.e.getClass());//class java.lang.String
        Person1 p1 =  new Person1(11);
        System.out.println(p1.e.getClass());//class java.lang.Integer
        Person1 p2 =  new Person1();
        System.out.println(p2.e);//null
    }
}
class Person1<E> {
    E e;
​
    public Person1() {
    }
​
    public Person1(E e) {
        this.e = e;
    }
​
    @Override
    public String toString() {
        return "Person1{" +
                "e=" + e +
                '}';
    }
}
​

2、泛型的语法

  • 泛型的声明

    1. interface 接口 <T>{} 和 class 类 <k,v>{}

    2. 其中 T,k,v不代表值,而是表示数据类型

    3. 任意字母都可以 指定一般都是使用T,K,V,E这些

  • 泛型的实例化

    1. List<String> list = new ArrayList<>();

    2. Iterator<Customer> iterator = customers.iterator();

3.使用细节

自定义泛型类

  1. 泛型只能是引用数据类型

  2. 在指定泛型具体类型后,可以传入该类型或者其子类型

  3. 如果不添加泛型 默认泛型是Object类型

  4. 普通成员可以使用泛型(属性,方法)

  5. 使用泛型的数组,不能初始化

  6. 静态方法不能使用类的泛型

  7. 泛型类的类型,是在创建对象的时候确定的(因为创建对象的时候,需要指定确定类型)

package com.sofwin.controller;
​
/**
 * @author: wentao
 * @date: 2022/11/2 20:36
 * @version: 1.0
 * @description: 自定义泛型
 */
public class CustomGeneric {
​
}
//1.Tiger类后有泛型  --所以我们吧tiger就称为自定义泛型类
//2. T R M 是泛型标识符,一般是单个大写字母
//3.泛型的标识符可以有多个
//4.普通成员可以使用泛型(属性 方法)
//5. 使用泛型数组不能初始化
//6.静态方法不能使用泛型
//    也是泛型是实例化的时候指定,  但是出发类的时候 可以调用静态方法
//      这个时候不知道泛型的类型
class  Tiger<T,R,M> {
    String name;
    R r;  //属性使用了泛型
    T t;
    M m;
    //泛型的类型是对象实例化的时候指定
    //但是这个类中数组  在类加载的时候就初始化了
    // 因此当数组实例化的时候 T还不知道什么类型  无法分配空间
    //因此只能声明  不能实例化
//    T[] ts = new T[8];
    T[] ts ;
    public Tiger(String name, R r, T t, M m) {
        this.name = name;
        this.r = r;
        this.t = t;
        this.m = m;
    }
​
    public String getName() {
        return name;
    }
​
    public void setName(String name) {
        this.name = name;
    }
    //返回类型使用泛型
    public R getR() {
        return r;
    }
    //方法使用泛型
    public void setR(R r) {
        this.r = r;
    }
​
    public T getT() {
        return t;
    }
​
    public void setT(T t) {
        this.t = t;
    }
​
    public M getM() {
        return m;
    }
​
    public void setM(M m) {
        this.m = m;
    }
}

自定义泛型接口

  1. 接口中,静态成员也不能使用泛型

  2. 泛型接口的类型,在继承接口或者实现接口时确定

  3. 没有指定类型,默认为Object

    
    ​
    /**
     * @author: wentao
     * @date: 2022/11/2 20:58
     * @version: 1.0
     * @description: 自定义泛型接口
     */
    public class InterfaceGeneric1 {
        public static void main(String[]args){
    ​
        }
    }
    ​
    ​
    ​
    //没有指定默认是Object
    class  UUTsb implements  Usb {
    ​
    ​
        @Override
        public Object get(Object o) {
            return null;
        }
    ​
        @Override
        public void hi(Object o) {
    ​
        }
    ​
        @Override
        public void run(Object r1, Object r2, Object u1, Object u2) {
    ​
        }
    }
    ​
    //实现的时候 可以自行指定了
    class  UUsb implements  Usb<Double,Float> {
    ​
        @Override
        public Float get(Double aDouble) {
            return null;
        }
    ​
        @Override
        public void hi(Float aFloat) {
    ​
        }
    ​
        @Override
        public void run(Float r1, Float r2, Double u1, Double u2) {
    ​
        }
    }
    interface   IUsb extends Usb<String ,Integer> {
    ​
    }
    /*
    1. 接口中,静态成员也不能使用翻新
    2. 泛型接口的类型,在继承接口或者实现接口时确定
    3. 没有指定类型,默认为Object
     */
    interface Usb<U,R> {
        //接口中属性 默认是 public static final的
        public  static  final  int i = 0;
    ​
    //    U u;
        //普通方法在接口中 可以使用泛型
        R get(U u);
    ​
        void  hi(R r);
    ​
        void  run(R r1, R r2, U u1, U u2);
    ​
        //在jdk8中 可以在接口中,使用默认方法
        default R method(U u) {
            return  null;
        }
    }

自定义泛型方法

基本语法

修饰符 <T,R...> 返回类型 方法名(参数列表)

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

  2. 当泛型方法被调用时,类型会确定

  3. public void ear(E e ) {} ,修饰符后没有<T,R..> eat方法不是泛型方法,而是使用了泛型

package com.sofwin.controller;
​
/**
 * @author: wentao
 * @date: 2022/11/2 21:30
 * @version: 1.0
 * @description: 泛型方法
 */
public class MethodGeneric1 {
    public static void main(String[]args){
​
        Car car = new  Car();
        // 当泛型方法被调用时,类型会确定
        //传入值的类型  编译器就自动确定了
        car.fly("str");
        car.fly(1);
    }
}
//泛型方法 可以定义在普通类中,也可以定义在泛型类中
class  Car {
    //普通方法
    public  void run() {}
​
    //泛型方法
    //<T,R>就是泛型  是提供给fly使用的
    public <T,R> void fly(T t) {
        System.out.println(t.getClass());
    }
    public <T,R> void fly(T t,R r) {
        System.out.println(t.getClass());
    }
}
​
class  Car2 extends  Car {
    @Override
    public <T, R> void fly(T t) {
        
    }
}
//也可以定义在泛型类
class  Fish<T,R> {
     public void  run () {}
​
     public <W,Q>  void  ear(W w) {}
}
​

4.泛型的继承和通配符

  1. 泛型不具备继承性

    List<Object> list = new ArrayList<String>() 是不对的

  2. <?>支持任意泛型类型

  3. <? extends A> 支持A类以及A类的子类,规定了泛型的上限

  4. <? super A> 支持A类以及A类的父类 不限于直接父类,规定了泛型的下限

import org.omg.CORBA.PUBLIC_MEMBER;
​
import java.util.ArrayList;
import java.util.List;
​
/**
 * @author: wentao
 * @date: 2022/11/2 22:16
 * @version: 1.0
 * @description: 泛型的基础和通配符
 */
public class GenericExtends {
    public static void main(String[]args){
        Object o = new String("xx");
         //1.泛型没有继承性
        //这个就不可以了
//        List<Object> list = new ArrayList<String>();
​
        //举例说明下面的方法
        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<>();
​
        //        1. <?>支持任意泛型类型
        printCollection(list1);
        printCollection(list2);
        printCollection(list3);
        printCollection(list4);
        printCollection(list5);
​
        //        2. <? extends A> 支持A类以及A类的子类,规定了泛型的上限
      //  printCollection2(list1);  //error  Object是A类的父类不是子类
      //  printCollection2(list2);  //error String没有关系
        printCollection2(list3); //ok 是AA类  
        printCollection2(list4); //ok 是AA类的子类
        printCollection2(list5);//ok 是AA类的子类(孙子)
​
        //        3. <? super A> 支持A类以及A类的父类  不限于直接父类,规定了泛型的下限
    printCollection3(list1); //ok Object是A类的父类 
   // printCollection3(list2); //error String不是 A类的父类  
    printCollection3(list3);  //AA类是可以的
   // printCollection3(list4);//error 是AA类的子类
   // printCollection3(list5);//error 是AA类的子类(孙子)
    }
    //        1. <?>支持任意泛型类型
    public static  void printCollection(List<?> c) {
        for (Object o : c) {
            System.out.println(o);
        }
    }
    
    //        2. <? extends A> 支持A类以及A类的子类,规定了泛型的上限
    public static  void printCollection2(List<? extends  AA> c) {
        for (Object o : c) {
            System.out.println(o);
        }
    }
​
    //        3. <? super A> 支持A类以及A类的父类  不限于直接父类,规定了泛型的下限
    public static  void printCollection3(List<? super   AA> c) {
        for (Object o : c) {
            System.out.println(o);
        }
    }
}
​
class  AA {
    
}
​
class  BB extends AA {
    
}
​
class  CC extends  BB {
    
}
​
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值