IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发测试 -> day20_泛型 -> 正文阅读

[开发测试]day20_泛型

泛型的概述

由来:

在Java中我们在声明方法时,当在完成方法功能时如果有未知的数据需要参与,这些未知的数据需要在调用方法时才能确定,那么我们把这样的数据通过形参表示。那么在方法体中,用这个形参名来代表那个未知的数据,而调用者在调用时,对应的传入值就可以了。

受以上两启发,JDK1.5设计了泛型的概念。泛型即为“类型参数”,这个类型参数在声明它的类、接口或方法中,代表未知的通用的类型。<类型>这种语法形式就叫泛型。

泛型的定义

  • 一种未知的数据类型,在使用的时候确定其具体的数据类型。

泛型的好处

  • 集合不使用泛型的时候,存的时候什么类型都能存。但取出来的时候,需要做类型判断,复杂繁琐也容易出错。使用泛型在编译期直接对类型作出了控制,只能存储泛型定义的数据。如果有了泛型并使用泛型,那么既能保证安全,又能简化代码。因为把不安全的因素在编译期间就排除了;既然通过了编译,那么类型一定是符合要求的,就避免了类型转换。

在哪里可以声明类型变量<T>

在方法丶类丶接口上可以声明泛型

  • 声明类或接口时,在类名或接口名后面声明类型变量,我们把这样的类或接口称为泛型类或泛型接口
  • 声明方法时,在【修饰符】与返回值类型之间声明类型变量,我们把声明(是声明不是单纯的使用)了类型变量的方法称为泛型方法

含有泛型的类

语法格式:

注意:

  • <代表泛型的变量>:可以是一个或多个类型变量,一般都是使用单个的大写字母表示。例如:<T>、<K,V>等。
  • <代表泛型的变量>中的类型变量不能用于静态成员上。

应用场景

  • 当类中的成员变量或者成员方法的形参类型\返回值类型不确定的时候,就可以把该类定义为含有泛型的类

?代码示例

//定义含有泛型的类
class MyArrayList<E>{
    
    //含有泛型的变量
    E e;

    //含有泛型的方法
    public void add(E e){
        System.out.println("含有泛型的方法");

    }
    //含有泛型的方法
    public E get(E index){
        return  index;
    }

}

怎么使用含有泛型的类

创建该类对象的时候,确定该类泛型的具体数据类型。泛型的具体数据类型必须是引用数据类型,不能是基本数据类型。例如,ArrayList<String> list = new ArrayList<String>( )? ?此时,变量E的值就是String类型,那么我们的类型就可以理解为:

class ArrayList<String>{ 
     public boolean add(String e){ }

     public String get(int index){  }
     ...
}

?下面我们来使用自定义的泛型类。

public class Test {
    public static void main(String[] args) {
        //泛型字符串类型
        MyArrayList<String> s1 = new MyArrayList<>();
        
        //泛型是Integer类型
        MyArrayList<Integer> s2 = new MyArrayList<>();
        
        //MyArrayList<double> s3 = new MyArrayList<>();// 错误,泛型必须是引用数据类型
        
    }
}

含有泛型的方法

语法格式:

?例如:java.util.Arrays类中的泛型方法

public static <T> List<T> asList(T... a){
    ....
}

我们自定义含有泛型的方法

public class Demo {
    // 定义含有泛型的方法
    public static <T> T method1(T t){
        return t;
    }
}

应用场景

  • ?如果一个类中,某个方法的参数类型或者返回值类型不确定的时候,可以把该方法定义为含有泛型的方法

怎么使用含有泛型的方法

  • 调用方法时,确定泛型的类型
class Test1{
    // 定义含有泛型的方法
    public static <T> T method(T t){
        return t;
    }
    public static void main(String[] args) {
        // 指定泛型的具体数据类型为Integer
        Integer i = method(100);
        System.out.println(i);// 100

        //指定泛型的具体数据类型为String
        String s = method("it");//
        System.out.println(s);
    }

}

含有泛型的接口

语法格式:

自定义含有泛型的接口

public interface IA<E> {

    public abstract void method1(E e);

    public default E method2(E e){
        return e;
    }
}

如何使用含有泛型的接口:

方式一:定义实现类时确定泛型的类型

// 通过实现类的方式确定接口泛型的具体数据类型
public class Imp1 implements IA<String> {
    @Override
    public void method1(String s) {

    }

    @Override
    public String method2(String s) {
        return null;
    }
}

此时,泛型E的值就是String类型。

方式二:始终不确定泛型的类型,直到创建对象时,确定泛型的类型

/*
实现类实现接口的时候不确定接口泛型的具体数据类型,
而是创建实现类对象的时候确定接口泛型的具体数据类型
 */
class Imp2<E> implements IA<E> {
    @Override
    public void method1(E e) {
        System.out.println("实现类 method1");
    }

    @Override
    public E method2(E e) {
        return e;
    }
}

class Test {
    public static void main(String[] args) {
        // 创建实现类对象的时候确定接口泛型的具体数据类型
        Imp2<String> imp1 = new Imp2<>();
        imp1.method1("it");
        String s1 = imp1.method2("it");
        System.out.println(s1);// it


        Imp2<Integer> imp2 = new Imp2<>();
        imp2.method1(100);
        Integer i = imp2.method2(100);
        System.out.println(i);// 100
    }
}

泛型通配符

泛型的通配符:不知道使用什么类型来接收的时候,此时可以使用?,?表示未知通配符。此时只能接受数据,不能往该集合中存储数据。

import java.util.ArrayList;

public class Demo01 {
    public static void main(String[] args) {

        // 关系:String继承Object,Integer继承Number,Number继承Objec
        ArrayList<Object> list1 = new ArrayList<>();
        ArrayList<String> list2 = new ArrayList<>();
        ArrayList<Integer> list3 = new ArrayList<>();
        ArrayList<Number> list4 = new ArrayList<>();
        list2.add("张三");
        list2.add("李四");
        list2.add("王五");
        method2(list2);
        method1(list2);

    }
    // 定义一个方法,可以接收以上4个集合
    public static void method1(ArrayList list){
        Object obj = list.get(0);
        list.add("jack");
        System.out.println("obj:"+obj);//obj:张三
        System.out.println("list:"+list);// list:[张三, 李四, 王五, jack]
    }

    /*
       通配符基本使用:
           泛型的通配符:不知道使用什么类型来接收的时候,此时可以使用?,?表示未知通配符。
           注意: 不能往该集合中存储数据,只能获取数据.
    */
    public static void method2(ArrayList<?> list){
        Object obj = list.get(0);
        //list.add("jack");// 编译报错,不能往该集合中存储数据,只能获取数据.
        System.out.println("obj:"+obj);// obj:张三
        System.out.println("list:"+list);// list:[张三, 李四, 王五]
    }
}

受限泛型

之前设置泛型的时候,实际上是可以任意设置的,只要是类就可以设置。但是在JAVA的泛型中可以指定一个泛型的上限下限。

泛型的上限

  • 格式: 类型名称 <? extends 类 > 对象名称
  • 意义: 只能接收该类型及其子类

泛型的下限

  • 格式 类型名称 <? super 类 > 对象名称
  • 意义 只能接收该类型及其父类型
import java.util.ArrayList;

public class Demo01 {
    public static void main(String[] args) {
        /*
            通配符高级使用----受限泛型:
                上限: <? extends 类名>  只能接收该类类型或者其子类类型
                下限: <? super 类名>   只能接收该类类型或者其父类类型
         */
        // 关系:String继承Object,Integer继承Number,Number继承Objec
        ArrayList<Object> list1 = new ArrayList<>();
        ArrayList<String> list2 = new ArrayList<>();
        ArrayList<Integer> list3 = new ArrayList<>();
        ArrayList<Number> list4 = new ArrayList<>();


        //因为 Integer继承Number
        method1(list4);
        method1(list3);

        //Integer继承Number,Number继承Object
        methoh2(list1);
        methoh2(list3);
        methoh2(list4);
    }

    // 定义一个方法,只可以接收只能接收Number类型或者其子类类型集合
    public static void method1(ArrayList<? extends Number> list) {

    }

    // 定义一个方法,只能接收Integer类型或者其父类类型
    public static void methoh2(ArrayList<? super Integer> list) {

    }

}
  开发测试 最新文章
pytest系列——allure之生成测试报告(Wind
某大厂软件测试岗一面笔试题+二面问答题面试
iperf 学习笔记
关于Python中使用selenium八大定位方法
【软件测试】为什么提升不了?8年测试总结再
软件测试复习
PHP笔记-Smarty模板引擎的使用
C++Test使用入门
【Java】单元测试
Net core 3.x 获取客户端地址
上一篇文章      下一篇文章      查看所有文章
加:2022-04-01 00:24:13  更:2022-04-01 00:24:41 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/18 0:15:35-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码