我是靠谱客的博主 落后书包,最近开发中收集的这篇文章主要介绍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、代码示例所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复