java泛型上限下限,通配符

Posted 好大的月亮

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java泛型上限下限,通配符相关的知识,希望对你有一定的参考价值。

概述

通常在定义一些class或者方法的时候都是执行类型的,但是遇到一些特殊场景,需要动态切换返回类型或者入参类型。此时固定声明的单一类型就不够用了。

上限和下限用数学中的范围来标识最明显了

  • 上限:(-∞~Person]
  • 下限:[Person~+∞)

类泛型声明

捞了个网上的demo,如下。

//多个类型变量可以用逗号分隔
public class Point<T, U> 
    private T pointX;
    private U pintY;
    public Point(T pointX, U pintY) 
        this.pointX = pointX;
        this.pintY = pintY;
    
    public void showPoint() 
        System.out.println(pointX);
        System.out.println(pintY);
    

方法泛型声明

捞了个网上的demo,如下。

public class FxMethod 

	//方法中引入类型变量,在返回类型前添加<>, 中间放置类型变量,多个类型变量用逗号分隔。
    public static <T> T getMiddleNumber(T ... numbers) 
        return null;
    
    
    public <T, U> void showNumber(T t, U u) 
        System.out.println("t = " + t);
        System.out.println("u = " + u);;
    

泛型上限和下限和无边界通配符

无边界通配符
可以传入任何类型,没有限制,相当于Object.

public CommonResult<?> add()
      return CommonResult.success();

上限

其实就是继承了一个父类,只要是父类或者子类都可以接受。
但是无法添加,这里add异常是因为list无法确定add的是fruit还是fruit的子类,
不过取出来的时候是可以明确知道里面的元素都是fruit的子类。

//AnimalWrapper构造方法可以接收Animal或者Animal的子类
class AnimalWrapper<T extends Animal> 
    private T animal;
    AnimalWrapper(T animal) 
        this.animal = animal;
    
    public void eat() 
       animal.eat();
    

class Animal 
    private String name;
    public void eat() 
        System.out.println("animal eat -----");
    

class Cat extends Animal 
    @Override
    public void eat() 
        System.out.println(" cat eat -----");
    

下限

定义了下限是Fruit,也就是说这个list里面的类型都是Fruit的父类,所以我们只能添加Fruit和他的子类。因为父类不确定,只明确了最低的子类Fruit。
但是取出来的时候因为不知道是哪个父类,所以只能用Object接收

但是接收(不是add)的时候是可以接收 >= Fruit 的集合的,比如

ArrayList<? super Person> list2 = null;
ArrayList<Object> list3 = null;
ArrayList<Person> list4 = null;
// list3的泛型是Object,超过Person类型肯定能被list2接收
list2 = list3;// 编译通过
// list4的泛型是Person,等于Person类型肯定能被list2接收
list2 = list4;// 编译通过

上限和下限的写入读取

集合中写入数据必须要确定这个元素。

上限的写入

demo中list add失败的原因是因为集合无法判断add进去的元素是什么类型的,可能是Fruit也可能是Fruit的子类Apple或者其他子类。

上限的读取
相对于写入,上限的读取可以确定集合内部的元素肯定是Fruit的子类

下限的写入
demo中List的下限是Fruit,addFruit的子类肯定没问题,因为父类可以接收子类

下限的读取
demo中无法确定读取出来的是Fruit还是Fruit的子类,所以只能用Object接收

以上是关于java泛型上限下限,通配符的主要内容,如果未能解决你的问题,请参考以下文章

Java 泛型通配符上限和通配符下限(正在整理)

JAVA泛型之<? extends T>:(通配符上限)和<? super T>(通配符下限)

泛型-类型通配符的下限

怎么区别java泛型的上限和下限??

java 泛型的上限与下限

泛型的上限和下限的Demo