我是靠谱客的博主 落后书包,最近开发中收集的这篇文章主要介绍Java 泛型中 <? extends T> 与 <? super T> 的区别1、? 和 T 是什么?2、代码示例,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

1、? 和 T 是什么?

? 是通配符(wildcard,记住这个单词,这样在报错时就知道说的是 ? 通配符),T 是类型变量。

  • 根据字面意思,<? extends T> 表示 任何继承自类型 T 的类型<? super T> 表示 任何是类型 T 的超类的类型

? extend/super Xx 不能用于声明处。
下面是用于表达式的正确例子:

Plate<? super Fruit> p = new Plate<Fruit>(new Fruit());
Plate<? extend Fruit> p1;

下面是用于声明处的错误例子:

public class Fruit {}
public class Plate<? extends Fruit> {} // 报错 Unexpected wildcard
  • T 则与问号不同,它只能用于声明处。<T extends Fruit> 表示声明一个类型变量 T,它是 Fruit 的一个具体子类不能写 <T super Fruit>,因为这样是没有任何意义的。原因是所有泛型在编译时都会被擦除,T 所代表的是一个 Fruit 的超类,但是具体是哪个类却是在运行时被决定的,编译器为了类型安全,只能做最大限度的包容,因此所有的 T 类型都会在编译器变为 Object。所以,写 <T super Fruit> 等同于写 <Object>,因此不支持 <T super Xx>

2、代码示例

2.1 定义实体

水果-所有水果父类

package com.ybw.generic.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
/**
* 水果
*
* @author ybw
* @version V1.0
* @className Fruit
* @date 2022/11/21
**/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Fruit {
/**
* @author: ybw
* @date: 2022/11/21
**/
private Long id;
/**
* 价格
*
* @author: ybw
* @date: 2022/11/21
**/
private BigDecimal price;
}

子类-苹果、桔子

package com.ybw.generic.dto;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* @author ybw
* @version V1.0
* @className Apple
* @date 2022/11/21
**/
@Data
@EqualsAndHashCode(callSuper = true)
public class Apple extends Fruit {
private String colour;
public Apple(Fruit fruit, String colour) {
super(fruit.getId(),fruit.getPrice());
this.colour = colour;
}
}
package com.ybw.generic.dto;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.math.BigDecimal;
/**
* @author ybw
* @version V1.0
* @className Orange
* @date 2022/11/21
**/
@Data
@EqualsAndHashCode(callSuper = true)
public class Orange extends Fruit {
/**
* 重量
*
* @author: ybw
* @date: 2022/11/21
**/
private BigDecimal weight;
public Orange(Fruit fruit, BigDecimal weight) {
super(fruit.getId(),fruit.getPrice());
this.weight = weight;
}
}

盘子

package com.ybw.generic.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
/**
* @author ybw
* @version V1.0
* @className Plate
* @date 2022/11/21
**/
@Data
@AllArgsConstructor
public class Plate<T> {
private T t;
}

2.2 实现类(泛型)

接口

package com.ybw.generic.service;
import com.ybw.generic.constant.Type;
import com.ybw.generic.dto.Fruit;
import com.ybw.generic.dto.Plate;
/**
* @author ybw
* @version V1.0
* @className FruitService
* @date 2022/11/21
**/
public interface FruitService {
/**
* 买水果
*
* @param type
* @methodName: buyFruit
* @return: java.util.List<com.ybw.generic.dto.Fruit>
* @author: ybw
* @date: 2022/11/21
**/
<T extends Fruit> Plate<T> buyFruit(Type type);
}

实现类

package com.ybw.generic.service.impl;
import com.ybw.generic.constant.Type;
import com.ybw.generic.dto.Apple;
import com.ybw.generic.dto.Fruit;
import com.ybw.generic.dto.Orange;
import com.ybw.generic.dto.Plate;
import com.ybw.generic.service.FruitService;
import java.math.BigDecimal;
/**
* @author ybw
* @version V1.0
* @className FruitServiceImpl
* @date 2022/11/21
**/
public class FruitServiceImpl implements FruitService {
@Override
public <T extends Fruit> Plate<T> buyFruit(Type type) {
switch (type) {
case APPLE -> {
Apple apple = new Apple(new Fruit(1L, BigDecimal.TEN), "红色");
return (Plate<T>) new Plate<>(apple);
}
case ORANGE -> {
Orange orange = new Orange(new Fruit(2L, BigDecimal.ONE), BigDecimal.TEN);
return (Plate<T>) new Plate<>(orange);
}
default -> {
}
}
return new Plate<>(null);
}
}

2.3 测试

package com.ybw.generic.service;
import com.alibaba.fastjson2.JSON;
import com.ybw.generic.constant.Type;
import com.ybw.generic.dto.Apple;
import com.ybw.generic.dto.Orange;
import com.ybw.generic.dto.Plate;
import com.ybw.generic.service.impl.FruitServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
@Slf4j
class FruitServiceTest {
@Test
void buyFruit() {
FruitService fruitService=new FruitServiceImpl();
Plate<Apple> applePlate=fruitService.buyFruit(Type.APPLE);
log.info("applePlate:{}", JSON.toJSONString(applePlate));
Plate<Orange> orangePlate=fruitService.buyFruit(Type.ORANGE);
log.info("orangePlate:{}", JSON.toJSONString(orangePlate));
}
}

最后

以上就是落后书包为你收集整理的Java 泛型中 <? extends T> 与 <? super T> 的区别1、? 和 T 是什么?2、代码示例的全部内容,希望文章能够帮你解决Java 泛型中 <? extends T> 与 <? super T> 的区别1、? 和 T 是什么?2、代码示例所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(49)

评论列表共有 0 条评论

立即
投稿
返回
顶部