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

泛型、泛型上限、泛型下限、泛型通配符

DAY8.1 Java核心基础

泛型在这里插入图片描述

Generics 是指在类定义时不指定类中信息的具体数据类型,而是用一个标识符来代替,当外部实例化对象时再指定具体的数据类型。

在定义类或者接口时不明确指定类中信息的具体数据类型,在实例化时再来指定具体的数据类型

极大地提升了类的扩展性,一个类可以装载各种不同的数据类型

泛型可以指代类中的成员变量数据类型,方法的返回值数据类型以及方法的参数数据类型。

基本使用:

定义一个Demo不指定类中的具体数据类型,用标识符代替

public class Demo<T>{
    private T t;

    public Demo(T t) {
        this.t = t;
    }

    public T getT() {
        return t;
    }

    public void setT(T t) {
        this.t = t;
    }
}
public static void main(String[] args) {
    Demo<String> hello = new Demo<>("hello");
    System.out.println(hello.getT());
    Demo<Integer> integerDemo = new Demo<>(11);
    System.out.println(integerDemo.getT());
}

输出:
image-20250309103252419

泛型也可以同时写多个泛型

public class Demo<T,A,B>{
    private T t;
    private A a;
    private B b;

    public Demo(T t, A a, B b) {
        this.t = t;
        this.a = a;
        this.b = b;
    }

    @Override
    public String toString() {
        return "Demo{" +
                "t=" + t +
                ", a=" + a +
                ", b=" + b +
                '}';
    }
}
public static void main(String[] args) {
    Demo<String, Integer, Float> hello = new Demo<>("hello", 1, 2.0f);
    System.out.println(hello);
}

image-20250309103908102

泛型通配符<?>:在不确定传入的数据类型的时候可以使用通配符

public static void main(String[] args) {
    ArrayList<Integer> integers = new ArrayList<>();
    test(integers);
    ArrayList<String> strings = new ArrayList<>();
    test(strings);
}
public static void  test(ArrayList<?> list) {
    System.out.println(list);
}

比如传入的参数是Interger类型和String类型,如果定义ArrayList list作为形参则String类型的数组无法传递

泛型的上限和下限

上限:类名<? extends A> 这个类型必须是A类的子类或者A类型本身
下限:类名<? super A> 这个类型必须是A类的父类或则A类型本身

public class Test {
    public static void main(String[] args) {
        ArrayList<Double> doubles = new ArrayList<>();
        doubles.add(1.0);
        test1(doubles);
        ArrayList<Object> strings = new ArrayList<>();
        strings.add("hello");
        test2(strings);
    }

    /**
     * 标识test1方法的list参数的类型是Number的子类或者是Number本身,比如 Integer、Double、Float...
     * @param list
     */
    public static void test1(ArrayList<? extends Number> list) {
        System.out.println(list);
    }

    /**
     * 表示test2方法的list参数的类型是String的父类或者是String本身,String or Object
     * @param list
     */
    public static void test2(ArrayList<? super String> list) {
        System.out.println(list);
    }
}

泛型接口

public interface MyInterface<T> {
    public T test();
}

实现类:

public class MyInterfaceImpl1 implements MyInterface<String>{
    public String t;

    public MyInterfaceImpl1(String t) {
        this.t = t;
    }

    @Override
    public String test() {
        return t;
    }
}
public class MyInterfaceImpl2<T> implements MyInterface<T>{
    public T t;

    public MyInterfaceImpl2(T t) {
        this.t = t;
    }

    @Override
    public T test() {
        return t;
    }
}

两个实现类,一个在实现的时候就定义了类型,一个没有定义,所以MyInterfaceImpl1就不能在使用的时候指定其它类型对象,就只能使用String类型

image-20250309110134125

正确测试代码:

public static void main(String[] args) {
    MyInterfaceImpl1 myInterfaceImpl1 = new MyInterfaceImpl1("123");
    System.out.println(myInterfaceImpl1.test());
    MyInterfaceImpl2<Integer> myInterfaceImpl2 = new MyInterfaceImpl2<>(123);
    System.out.println(myInterfaceImpl2.test());
}

相关文章:

  • java虚拟机(JVM)以及各种参数详解
  • 力扣-哈希表-844 比较含退格的字符串
  • 理解C语言中的extern关键字
  • 【机器人-基础知识】欧拉角、旋转矩阵和四元数
  • python爬虫碰到IP被封的情况,如何解决?
  • 【Rust并发编程深度解析:内存模型与异步运行时实现原理】
  • JavaScript API与WebRTC技术解析:EasyRTC嵌入式视频通话SDK的实现
  • vue3:密码加密解密实现
  • pdf合并工具
  • OpenGL(4)着色器
  • LearnOpenGL-笔记-其三
  • 文件跨国传输如何加速?UDP改造机制解析
  • vscode出现:No module named ‘requests‘ 问题的解决方法
  • 【AI】单台10卡4090 openEuler服务器离线部署kasm workspace 提供简单的GPU云服务 虚拟化桌面
  • 每天一篇《目标检测》文献(一)
  • Android Compose remember 详解
  • docker jar镜像打包
  • windows平台的ffmpeg编译使用
  • 国产化信创操作系统的电脑,能运行windows程序吗
  • 大三下找C++开发实习的感受分享
  • 人社部:将制定提前领取个人养老金相关办法
  • 我国将开展市场准入壁垒清理整治行动
  • 龚正会见委内瑞拉副总统罗德里格斯
  • 第1现场|无军用物资!伊朗港口爆炸已遇难40人伤1200人
  • 脱发后怎么把头发养回来?脱发自救指南来了
  • 5月动漫|“爱死机”即将回归,《明末》或是下一个大IP?