Java学习笔记:利用泛型动态的返回不同的类

环境

前言

最近在做代码迁移时,想写这么一个方法,我传入什么对象,其就返回什么对象;
传入的对象有继承关系,在处理完相应逻辑后,就返回该对象;

比如有如下两个类:

ExaminationBindBO  
     |___________ExaminationPkgBindBO

我希望我得到的效果是:

ExaminationPkgBindBO pkgBindBO = new ExaminationPkgBindBO();
ExaminationBindBO bindBO = new ExaminationBindBO();
ExaminationPkgBindBO bindBO = saveProductChannel(Lists.newArrayList(pkgBindBO));
ExaminationBindBO bindBO = saveProductChannel(Lists.newArrayList(bindBO));

关键saveProductChannel()这个方法怎么写?
一开始时间紧,没想出来,只写成了返回值为void的方法;

// 上界通配符
public void saveProductChannel(List<? extends ExaminationBindBO> request) {
	// 处理业务逻辑
}

后面闲下来又研究了下;

动态的返回不同的类

public <T extends ExaminationBindBO> T saveProductChannel(List<T> request) {
    // 处理业务逻辑
    return request.get(0);
}

如果想更动态的返回

public <T> List<T> saveProductChannel(Class<List<T>> request) {
    List<T> t = null;
    try {
        t = request.getDeclaredConstructor().newInstance();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return t;
}

后面在查阅资料中有了个疑问:

为什么方法参数中上界通配符只能写成这样<? extends ExaminationBindBO>而不能写成<T extends ExaminationBindBO>
拿上面例子举例:

// 正确
public void saveProductChannel(List<? extends ExaminationBindBO> request) {}
// 会报错
public void saveProductChannel(List<T extends ExaminationBindBO> request) {}

我可以理解为:没有声明T是哪里的,所以我尝试这么写:

// 会报错
public <T> void saveProductChannel(List<T extends ExaminationBindBO> request) {}

又报错了,我的理解:虽然在public和void之间定义了T,而方法参数中的<T extends ExaminationBindBO>是在使用T,并不能定义T,所以它报错了;
按照这样理解,那么我就到定义T的地方去写上界通配符

// 正确
public <T extends ExaminationBindBO> void saveProductChannel3(List<T> request) {
    T t = request.get(0);
}

这时我又思考:为什么在方法参数中<? extends ExaminationBindBO>不报错,而<T extends ExaminationBindBO>报错呢?

个人理解:

虽然?和T都表示不确定类型,但是T 是不确定中的确定类型,即要求你定义T是哪来的~
也就是方法 public和返回值 之间得写,这就是在定义,那么其继续关系自然就得在定义处来写了;
而<? extends ExaminationBindBO>中的?是不需要你定义哪来的,是真正的不确定类型,随便你哪来的都可以。

? 和 T 的区别

这两个都是不确定的通配符,其中?又叫无界通配符。在使用时,不需要定义?
T表示具体某个类型。在使用时,是需要定义T的;并且在代码中,可以对T进行操作,而?没办法操作。

应用场景

T 是一个 确定的 类型,通常用于泛型类和泛型方法的定义,?是一个 不确定 的类型,通常用于泛型方法的调用代码和形参,不能用于定义类和泛型方法。

不知道你会有觉得上面一会确定 一会不确定 这种描述感到困惑;
虽然?和T都是不确定通配符,但是在不确定的问题中,还是有确认的东西的。----- 我自己的理解

参考地址:

https://juejin.im/post/6844903917835419661
在java的泛型中super和extends的区别

好的,下面我将为你介绍如何在 Java 中建立泛型泛型方法,并进行调用。 首先,让我们看一下如何建立泛型泛型是指具有一个或多个型参数的。我们可以使用型参数来代替具体的数据型,从而使更通用、更灵活。例如,下面是一个简单的泛型示例: ```java public class Pair<T1, T2> { private T1 first; private T2 second; public Pair(T1 first, T2 second) { this.first = first; this.second = second; } public T1 getFirst() { return first; } public T2 getSecond() { return second; } } ``` 在上面的示例中,我们定义了一个 `Pair` ,该有两个型参数 `T1` 和 `T2`。我们可以使用这个来表示一对值,其中一个值的型是 `T1`,另一个值的型是 `T2`。 接下来,让我们看一下如何建立泛型方法。泛型方法是指具有一个或多个型参数的方法。我们可以使用型参数来代替具体的数据型,从而使方法更通用、更灵活。例如,下面是一个简单的泛型方法示例: ```java public class Utils { public static <T> void printArray(T[] array) { for (T element : array) { System.out.print(element + " "); } System.out.println(); } } ``` 在上面的示例中,我们定义了一个 `printArray` 方法,该方法有一个型参数 `T`。我们可以使用这个方法来打印任何型的数组。 现在,我们来看一下如何调用泛型泛型方法。对于泛型,我们需要在创建对象时指定型参数。例如: ```java Pair<Integer, String> p1 = new Pair<>(1, "hello"); Pair<Double, Double> p2 = new Pair<>(3.14, 2.71); ``` 在上面的示例中,我们创建了两个 `Pair` 对象,一个用于存储一个 `Integer` 和一个 `String`,另一个用于存储两个 `Double`。 对于泛型方法,我们需要在调用方法时指定型参数。例如: ```java Integer[] arr1 = {1, 2, 3, 4, 5}; String[] arr2 = {"hello", "world"}; Utils.printArray(arr1); // 输出:1 2 3 4 5 Utils.printArray(arr2); // 输出:hello world ``` 在上面的示例中,我们调用了 `printArray` 方法,并传递了两个不同型的数组作为参数。由于该方法是泛型方法,因此编译器会根据传递的参数型自动推断出型参数 `T` 的具体型。 希望这个示例能够帮到你,祝你学习愉快!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

山鬼谣me

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值