Java之通配符

简介: 通配符是用来解决泛型无法协变的问题的,协变指的就是如果 Student 是 Person 的子类,那么 List 也应该是 List 的子类。但是泛型是不支持这样的父子类关系的。如下代码示例:

通配符解决的问题


通配符是用来解决泛型无法协变的问题的,协变指的就是如果 Student 是 Person 的子类,那么 List 也应该是 List 的子类。但是泛型是不支持这样的父子类关系的。如下代码示例:


class Message<T> {
    private T message;
    public T getMessage() {
        return message;
    }
    public void setMessage(T message) {
        this.message=message;
    }
}
public class TestDemo {
    public static void main(String[] args) {
        Message<String> message1=new Message<>();
        message1.setMessage("哈喽啊");
        fun(message1);
        Message<Integer> message2=new Message<>();
        message2.setMessage(10);
        fun(message2);
    }
    public static void fun(Message<String> temp) {
        System.out.println(temp.getMessage());
    }
}

微信图片_20230110234245.png

如上图所示,会在此处编译报错,这是因为fun函数内的参数类型为String类型,不支持Integer类型。


我们需要的解决方案:可以接收所有的泛型类型,但是又不能够让用户随意修改。这种情况就需要使用通配符"?"来处理。


public class TestDemo {
    public static void main(String[] args) {
        Message<String> message1=new Message<>();
        message1.setMessage("哈喽啊");
        fun(message1);
        Message<Integer> message2=new Message<>();
        message2.setMessage(10);
        fun(message2);
    }
    public static void fun(Message<?> temp) {
        System.out.println(temp.getMessage());
    }
}


在"?"的基础上又产生了两个子通配符:


? extends 类:设置泛型上限

? super 类:设置泛型下限


通配符的上界


语法:


<? extends 上界> 
<? extends Number>//可以传入的实参类型是Number或者Number的子类


微信图片_20230110234237.png


class Food {
}
class Fruit extends Food {
}
class Apple extends Fruit {
}
class Banana extends Fruit {
}
class Message<T> {
    private T message;
    public T getMessage() {
        return message;
    }
    public void setMessage(T message) {
        this.message=message;
    }
}
public class Demo1 {
    public static void main(String[] args) {
        Message<Apple> message1=new Message<>();
        message1.setMessage(new Apple());
        fun(message1);
        Message<Banana> message2=new Message<>();
        message2.setMessage(new Banana());
        fun(message2);
    }
    //这里只要是Fruit或者Fruit的子类即可
    public static void fun(Message<? extends Fruit> temp) {
        /*
         这里无法确定 temp 引用的是哪个子类对象 所以无法进行修改
        temp.setMessage(new Banana());
        temp.setMessage(new Apple());
         */
        //放的都是Fruit或者Fruit的子类,所以 可以直接使用  Fruit 接收
        Fruit fruit = temp.getMessage();
        System.out.println(temp.getMessage());
    }
}


通配符的上界,不能进行写入数据,只能进行读取数据。


通配符的下界


语法:


<? super 下界> 
<? super Integer>//代表 可以传入的实参的类型是Integer或者Integer的父类类型


微信图片_20230110234229.png

class Food {
}
class Fruit extends Food {
}
class Apple extends Fruit {
}
class Banana extends Fruit {
}
class Message<T> {
    private T message;
    public T getMessage() {
        return message;
    }
    public void setMessage(T message) {
        this.message=message;
    }
}
public class Demo1 {
    public static void main(String[] args) {
        Message<Fruit> message1=new Message<>();
        message1.setMessage(new Fruit());
        fun(message1);
        Message<Food> message2=new Message<>();
        message2.setMessage(new Food());
        fun(message2);
    }
    //这里只要是Fruit或者Fruit的父类即可
    public static void fun(Message<? super Fruit> temp) {
        //此时可以修改,添加的是Fruit或者Fruit的子类
        temp.setMessage(new Banana());
        temp.setMessage(new Apple());
        //Fruit fruit=temp.getMessage();不能接收,这里无法确定是哪个父类
        System.out.println(temp.getMessage());//只能直接输出
    }
}


通配符的下界,不能进行读取数据,只能写入数据。

相关文章
|
8月前
|
安全 Java 开发者
Java 泛型中的通配符 T,E,K,V,?有去搞清楚吗?
本文介绍了Java泛型及其通配符的使用方法与作用。泛型是JDK5引入的特性,提供编译时类型安全检测,避免运行时类型转换异常。文中详细解析了常见通配符T、E、K、V、?的含义及应用场景,如无界通配符`&lt;?&gt;`、上界通配符`&lt;? extends T&gt;`和下界通配符`&lt;? super T&gt;`。通过代码示例,展示了泛型在类型安全、消除强制转换、代码复用和增强可读性等方面的优势。最后强调深入理解技术原理的重要性,以提升开发能力。
384 0
|
Java API 容器
Java泛型的继承和通配符
Java泛型的继承和通配符
110 1
|
安全 Java API
Java一分钟之-泛型通配符:上限与下限野蛮类型
【5月更文挑战第19天】Java中的泛型通配符用于增强方法参数和变量的灵活性。通配符上限`? extends T`允许读取`T`或其子类型的列表,而通配符下限`? super T`允许向`T`或其父类型的列表写入。野蛮类型不指定泛型,可能引发运行时异常。注意,不能创建泛型通配符实例,也无法同时指定上下限。理解和适度使用这些概念能提升代码的通用性和安全性,但也需兼顾可读性。
325 3
|
Python Java Go
Java每日一练(20230416) 三数之和、基本计算器、通配符匹配
Java每日一练(20230416) 三数之和、基本计算器、通配符匹配
203 0
Java每日一练(20230416) 三数之和、基本计算器、通配符匹配
|
Java 编译器
[java进阶]——泛型类、泛型方法、泛型接口、泛型的通配符
[java进阶]——泛型类、泛型方法、泛型接口、泛型的通配符
172 0
|
Java Go
【Java 泛型方法】泛型方法的定义和使用,泛型的通配符和泛型的上下限,泛型的注意事项
【Java 泛型方法】泛型方法的定义和使用,泛型的通配符和泛型的上下限,泛型的注意事项
128 0
|
Java
Java 中通配符的使用
Java 中通配符的使用
160 0
|
安全 Java
Java 泛型使用(类、方法、接口协议、类型通配符、通配符上下限)
Java 泛型使用(类、方法、接口协议、类型通配符、通配符上下限)
287 0
|
安全 Java 编译器
「 Java基础-泛型 」一篇文章说清楚Java泛型中的通配符T、E、K、V、N、?和Object的区别与含义
Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许开发者在编译时检测到非法的类型。 泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。 泛型(Generic type 或者 generics)是对 Java 语言的类型系统的一种扩展,以支持创建可以按类型进行参数化的类。 可以把类型参数看作是使用参数化类型时指定的类型的一个占位符,就像方法的形式参数是运行时传递的值的占位符一样。
「 Java基础-泛型 」一篇文章说清楚Java泛型中的通配符T、E、K、V、N、?和Object的区别与含义
java202303java学习笔记第三十一天泛型通配符和综合练习1
java202303java学习笔记第三十一天泛型通配符和综合练习1
109 0