当前位置: 首页 > article >正文

JavaSE——泛型编程

一、为什么要引入泛型编程

        看这段代码:

//传统方法:
ArrayList list = new ArrayList();
list.add(new Dog("小黄",5));
list.add(new Dog("小黑",1));
list.add(new Dog("小财",10));
//编译器发现不了这种问题,它是不安全的
list.add(new Cat("招财猫",8));
for(Object o:list){
    //向下转型
    Dog d = (Dog)o;
    System.out.println(d.getName() + "-" + d.getAge());
}

        传统方法的问题分析:

  1. 不能对加入到集合中的数据类型进行约束,这里编译器发现不了,但是实际会抛出异常。
  2. 遍历的时候,需要进行类型转换,如果集合中的数据量较大,对效率有影响。

泛型解决上面这个问题:

//ArrayList<Dog>表示存放到ArrayList集合中的元素是Dog类型
//如果编译器发现添加的类型不满足要求就会报错
//遍历时可以直接取出Dog类型而不是Object
ArrayList<Dog> list = new ArrayList<Dog>();
list.add(new Dog("小黄",5));
list.add(new Dog("小黑",1));
list.add(new Dog("小财",10));
//现在编译器可以发现这种问题,它是不安全的
//list.add(new Cat("招财猫",8));
//可以直接取出Dog,不需要向下转型
for(Dog o:list){
    System.out.println(o.getName() + "-" + o.getAge());
}

二、什么是泛型 

  1. 泛型又称参数化类型,解决数据类型的安全性问题。
  2. 在类声明或者实例化只要指定化需要的具体的类型即可。
  3. Java泛型可以保证如果程序在编译时没有发出警告,运行时就不会产生ClassCastException异常。
  4. 泛型的作用是:可以在类声明时通过一个标识表示类中某个属性的类型,或者某个方法的返回值的类型,或者是参数类型。
class persop<E> {
    //E表示 s的数据类型,该数据类型在定义person对象的时候确定,
    // 即在编译期间,就确定E是什么类型
    E s;
    //也可以是参数类型
    public persop(E s) {
        this.s = s;
    }
    //做返回类型
    public E f(){
        return s;
    }
}

三、泛型的使用细节

  1. 泛型必须是引用类型。
  2. 在给泛型指定具体类型后,可以传入子类型。
  3. 泛型使用形式:
List<Integer> list1 = new ArrayList<Integer>();
ArrayList<Integer> list2 = new ArrayList<Integer>();

List<Integer> list3 = new ArratList<>();
ArrayList<Integer> list4 = new ArrayList<>();

//这样写,泛型默认是Object
ArrayList arraylist = new ArrayList();

四、自定义泛型

4.1自定义泛型类

基本语法:

class 类名<T,R...>{//...表示可以有多个泛型
    成员
}
  1. 普通成员可以使用泛型。
  2. 使用泛型的数组不可以初始化。
  3. 静态方法中,不能使用类的泛型。
  4. 泛型类的类型,是在创建对象时确定的(因为创建对象时,需要指定类型)。
  5. 如果在创建对象时没有指定类型,默认为Object 。
class Tiger<T,R,M>{
    String name;
    //属性使用泛型
    R r;
    M m;
    T t;
    //数组在new时不能确定T的类型,不能直接实例化
    //T[] ts = new T[8];
    public Tiger(String name, R r, M m, T t){//构造器使用泛型
        this.name = name;
        this.r = r;
        this.m = m;
        this.t = t;
    }

    //静态方法不能使用泛型
    //静态是和类相关的,在类加载时,对象还没有初始化
    //此时如果静态方法和静态属性使用了泛型,JVM就无法完成初始化。
    //public static void fun(M m){}
}

4.2自定义泛型接口 

基本语法:

interface 接口名<T,R...>{
}
  1. 接口中,静态成员不能使用泛型。
  2. 泛型接口的类型在继承接口或者实现接口时确定。
  3. 没有指定类型则默认为Object。 
interface IUsb<U,R>{}
//实现时指定
class c implements IUsb<String,Interger>

//继承时指定
interface MyInterface extends IUsb<String,Integer>{}、
//这时会自动替换
class D implements MyInterface{}

4.3自定义泛型方法 

修饰符<T,R...>返回类型 方法名(参数列表){}
  1. 泛型方法可以定义在普通类中,也可以定义在泛型类中。
  2. 当泛型方法被调用时,类型会确定。

4.4泛型的继承

  1. 泛型不具备继承性
    //错误,泛型是不存在继承的
    List<Object> list = new ArrayList<String>();
  2. <?>表示支持任意泛型。
  3. <? extends A>表示支持A类以及A类的子类,规定了泛型的上限。
  4. <? super A>表示A类以及A类的父类,不限于直接父类,规定了泛型的下限。
public static void printColleaction1(List<?> a) {}

//表示可以接收AA类或者AA类的子类
public static void printColleaction2(List<? extends AA> a) {}

//表示可以接收AA类以及AA类的父类
public static void printColleaction3(List<? super AA> a) {}


class AA{}
class BB extends AA{}
class CC extends BB{}

 

 

 

        


http://www.kler.cn/a/429090.html

相关文章:

  • LLM - 大模型 ScallingLaws 的 C=6ND 公式推导 教程(1)
  • lvm快照备份技术详细知识点
  • Web自动化:Cypress 测试框架概述
  • 个人vue3-学习笔记
  • Qiankun 微前端框架全面解析:架构、原理与最佳实践
  • springboot如何解析 Map 的泛型信息来确定要注入哪些 Bean?
  • 运输层6——TCP流量控制
  • LDR6500:音频双C支持,数字与模拟的完美结合
  • Mac通过Windows App远程访问windows电脑报错0x104的解决办法
  • iPhone怎么一键删除照片:快速清理存储空间
  • 关于我、重生到500年前凭借C语言改变世界科技vlog.18——内存函数
  • Python的3D可视化库vedo 1-3 (visual模块)网格对象的线和面、图片的属性
  • 【Python】批量下载抖音视频
  • 通过ThinkPad小红点键盘左右滑动页面
  • OpenCV 图像变换与处理实战
  • 2.Flink的项目初始化和Hello-world
  • 「Mac玩转仓颉内测版47」小学奥数篇10 - 数列求和
  • 电脑无法识别usb设备怎么办?电脑无法识别usb解决方法
  • 基于STM32的DS18B20温度报警器_可调上下限Proteus仿真设计(仿真+程序+设计报告+讲解视频)
  • 鸿蒙ZRouter动态路由框架—服务路由
  • java+springboot+mysql游乐园管理系统
  • 重生之我在学Vue-- Vue3 学习路径总览
  • 生成SSH秘钥文件
  • Python实现ARIMA-LSTM回归模型预测股票价格项目实战
  • 深入了解架构中常见的4种缓存模式及其实现
  • Linux —— 管理文件