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

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

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());
}

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

相关文章:

  • Codeforces Round 566 (Div. 2) E. Product Oriented Recurrence 矩阵加速、欧拉降幂
  • 自然语言模型NLP :tensorflow搭建情感分析模型
  • 企业数据挖掘平台×DeepSeek强强联合,多种应用场景适用
  • 实现静态网络爬虫(入门篇)
  • 数据结构--【栈与队列】笔记
  • 计算机视觉算法实战——犯罪行为检测(主页有源码)
  • C++复试笔记(一)
  • PreTrainedModel 类代码分析:_load_pretrained_model
  • 基于Django创建一个WEB后端框架(DjangoRestFramework+MySQL)流程
  • 异常与日志简易版本
  • OpenCV 作为第三方库编译并在 C++ 项目中使用
  • 关于sqlalchemy的使用
  • 【备赛】stm32如何实现定时器延时/解决定时器中断刚开启就进中断的问题
  • 10. 【.NET 8 实战--孢子记账--从单体到微服务--转向微服务】--微服务基础工具与技术--Ocelot 网关--认证
  • uniApp实战二:仿今日相机水印功能
  • 猫耳大型活动提效——组件低代码化
  • 服务器数据恢复—raid5阵列中硬盘出现坏道的数据恢复流程
  • Spring Boot启动流程及源码实现深度解析
  • 前端非技术性场景面试题
  • 长上下文 GRPO