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 小米 华为 单反 装机 图拉丁
 
   -> 开发测试 -> 泛型详解及使用及通配符、数组(二) -> 正文阅读

[开发测试]泛型详解及使用及通配符、数组(二)

参考资料文档见上一节

目录

一、通配符概述

1.概述

2.使用条件

3.使用方法

(1)简介

?(2).通配符上限

(3).通配符下限

4.拓展

?二、泛型数组


一、通配符概述

1.概述

  • 在使用泛型方法时可以发现,虽然这样处理可以扩大使用范围,但是由于范围太大了,导致很多功能书写起来很困难,比如:
  • 我们定义了一个类??Grandfather
@Data
public class Grandfather {

    private String Name;

    private Integer Age;

}
  • 我们要获取? List<Grandfather>? 第一个元素的name值 ,用泛型的话只能用反射来做
    private <T> String getName(List<T> list){

        /**
         * 这里只能用反射来获取到
         * list第一个元素的 name
         */
        return null;
    }
  • ?但是我们用通配符的话,就不用使用反射了

2.使用条件

  • 通配符的使用前提是:
  • 1.必须共用同一个父类,或者构成继承关系,

如:Integer 和 Number类,以及自定义的有类(有共同父类或构成继承关系)

  • 2.方法的形参是一个可填泛型的方法、数据结构
    //用泛型方式实现
    private <T> String method_01(List<T> list){
        return null;
    }

将尖括号里的T替换成通配符为

    //用上限式通配符实现
    private String method_02(List<? extends Father> list){
        return null;
    }

?

那么错误的写法是:

不能替换没有方法或者数据结构包裹的泛型?

3.使用方法

(1)简介

  • 既然通配符必须使用在继承系统中的类,那么约束的话就是约束公用的父类和共用的子类,即通配符的上限和下限

  • ?比如我们三个类,它们构成继承关系
@Data
public class Grandfather {

    private String Name;

    private Integer Age;

}
@Data
public class Father extends Grandfather{

}
@Data
public class Son extends Father{

}

?(2).通配符上限

  • 通配符上限的语法是:

<? extends TopClass>

即所有的类都必须是TopClass自身以及子类

(3).通配符下限

  • 通配符下限的语法是:
<? super BottomClass>

即所有的类都必须是BottomClass自身以及父类

(4).综合使用

  • 根据上面定义的三个类,给出下面的综合使用,目的是统计输入list的年龄和
//测试通配符
public class Demo01 {

    public static Random random = new Random();

    //用泛型方式实现
    private <T> String method_01(List<T> list) {
        //泛型方式是无法统计年龄的总数的
        StringBuilder str = new StringBuilder();
        list.forEach(x -> {
            str.append(x.toString());
        });
        return str.toString();
    }

    //用上限式通配符实现
    private String method_02(List<? extends Father> list) {
        Integer result = 0;
        for (Father father : list) {
            result = +father.getAge();
        }
        return String.valueOf(result);
    }

    //用下限式通配符实现
    private String method_03(List<? super Father> list) {
        StringBuilder str = new StringBuilder();
        list.forEach(x -> {
            str.append(x.toString());
        });
        return str.toString();
    }

}
  • 可以看到,用泛型和下限方式是实现不了的,用上限方式是可以实现的,并且上限和下限都规定在了father这一层,那么对这些方法的调用
//测试通配符
public class Demo01 {

    public static Random random = new Random();

    //用泛型方式实现
    private <T> String method_01(List<T> list) {
        //泛型方式是无法统计年龄的总数的
        StringBuilder str = new StringBuilder();
        list.forEach(x -> {
            str.append(x.toString());
        });
        return str.toString();
    }

    //用上限式通配符实现
    private String method_02(List<? extends Father> list) {
        Integer result = 0;
        for (Father father : list) {
            result = +father.getAge();
        }
        return String.valueOf(result);
    }

    //用下限式通配符实现
    private String method_03(List<? super Father> list) {
        StringBuilder str = new StringBuilder();
        list.forEach(x -> {
            str.append(x.toString());
        });
        return str.toString();
    }

    @Test
    public void test_01()throws Exception{
        List<Grandfather> list1 = (List<Grandfather>) getList(Grandfather.class);
        List<Father> list2 = (List<Father>) getList(Father.class);
        List<Son> list3 = (List<Son>) getList(Son.class);

        System.out.println(method_01(list1));

        System.out.println(method_02(list1));
        System.out.println(method_02(list2));
        System.out.println(method_02(list3));

        System.out.println(method_03(list1));
        System.out.println(method_03(list2));
        System.out.println(method_03(list3));


    }

    private List<? extends Grandfather> getList(Class<? extends Grandfather> clazz) throws Exception{
        List<Grandfather> list = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            Grandfather instance = clazz.newInstance();
            instance.setAge(random.nextInt(100));
            instance.setName(RandomStringUtils.randomAlphanumeric(5));
            list.add(instance);
        }
        return list;
    }

}

?

  • ?那么这就是关于通配符的使用

4.拓展

  • 当然,泛型也是支持通配符的,但是仅仅是起到约束作用
public class Demo02 <T extends Father>{

    public <E extends Son> void  getName(List<E> list){

        for (E e : list) {

        }
    }
}

?二、泛型数组

  • 创建方式1:可以声明带泛型的数组引用,但是不能直接创建带泛型的数组对象
    @Test
    public void test_01(){
        ArrayList<String>[] listArr = new ArrayList[5];

        ArrayList<String> strList = new ArrayList<>();
        strList.add("abc");
        listArr[0] = strList;
        String s = listArr[0].get(0);
        System.out.println(s);
    }
  • ?创建方式2:可以通过java.lang.reflect.ArraynewInstance(Class<T>,int)创建T[]数组
public class Fruit<T> {
    private T[] array;

    public Fruit(Class<T> clz, int length){
        //通过Array.newInstance创建泛型数组
        array = (T[]) Array.newInstance(clz, length);
    }
    /**
     * 填充数组
     * @param index
     * @param item
     */
    public void put(int index, T item) {
        array[index] = item;
    }

    /**
     * 获取数组元素
     * @param index
     * @return
     */
    public T get(int index) {
        return array[index];
    }

    public T[] getArray() {
        return array;
    }
}

?

    @Test
    public void test_02(){
        Fruit<String> fruit = new Fruit<>(String.class,3);
        fruit.put(0,"苹果");
        fruit.put(1,"西瓜");
        fruit.put(2,"香蕉");

        System.out.println(Arrays.toString(fruit.getArray()));
        String s1 = fruit.get(2);
        System.out.println(s1);
    }

  开发测试 最新文章
pytest系列——allure之生成测试报告(Wind
某大厂软件测试岗一面笔试题+二面问答题面试
iperf 学习笔记
关于Python中使用selenium八大定位方法
【软件测试】为什么提升不了?8年测试总结再
软件测试复习
PHP笔记-Smarty模板引擎的使用
C++Test使用入门
【Java】单元测试
Net core 3.x 获取客户端地址
上一篇文章      下一篇文章      查看所有文章
加:2022-04-22 19:07:17  更:2022-04-22 19:09:36 
 
开发: 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年5日历 -2024/5/19 7:31:43-

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