【Java 泛型】java泛型‘T‘与‘?‘区别

有时候我们会在业务中进行泛型设计的扩展。其中用的比较多的就是T , ?

泛型就相当于标签

形式:<>  

集合容器类在设计阶段/声明阶段不能确定这个容器到底实际存的是什么类型的对象,所以在JDK1.5之前只能把元素类型设计为Object,

JDK1.5之 后使用泛型来解决。因为这个时候除了元素的类型不确定,其他的部分是确定的,例如关于这个元素如何保存,如何管理等是确定的,因此此时把元素的类型设计成一个参数,这个类型参数叫做泛型。

Collection<E>, List<E>, ArrayList<E> 这个<E>就是类型参数,即泛型。

结论:'T'指的是某一类具体的对象,'?'可以表示成占位符,表明多种数据类型;

示例:可以看到show1方法中我们使用了T,大家都知道这是泛型的常见写法,那么这里的T指的是某一类具体的对象,list集合里只能存放同一类型数据,如果插入不同类型数据则会报错。
那么show2方法中我们使用的是?,可以看到在void前面并没有<T>,?可以表示成占位符,它自己也不知道list集合中会存放多少种类型的数据,所以这样就表明我们的list中存放N种数据类型也是可以的。
我们通过一段测试代码来直观的感受一下二者的区别吧:
 

public static <T> void show1(List<T> list){
 for (Object object : list) {
        System.out.println(object.toString());
    }
}
public static void show2(List<?> list) {
    for (Object object : list) {
        System.out.println(object);
    }
}
public static void test(){
   List<Student> list1 = new ArrayList<>();
   list1.add(new Student("zhangsan",18,0));
   list1.add(new Student("lisi",28,0));
   list1.add(new Student("wangwu",24,1));
   //这里如果add(new Teacher(...));就会报错,因为我们已经给List指定了数据类型为Student
   show1(list1);
   System.out.println("************分割线**************");
   //这里我们并没有给List指定具体的数据类型,可以存放多种类型数据
   List list2 = new ArrayList<>();
   list2.add(new Student("zhaoliu",22,1));
   list2.add(new Teacher("sunba",30,0));
   show2(list2);
}

实际应用下:

分页响应对象类中返回的数据,我们可以定义为List<?> rows, 这里就不用T , 因为我们的类PageResult类没有定义泛型。  如果要写泛型T,是表示一个具体的属性,你需要在类上也声明好泛型T,这样在构建类的对象的时候,才能给泛型指定上具体的类型。

package com.tree.community.common.core.domain.page;


import org.apache.poi.ss.formula.functions.T;

import java.io.Serializable;
import java.util.List;

/**
 * @Description **分页数据统一封装响应对象**
 * @Author tree
 * @Date 2024/4/29 16:44
 */
public class PageResult implements Serializable {
    private static final long serialVersionUID = -6529723591699684110L;

    /** 总记录数 */
    private long total;

    /** 列表数据 */
    private List<?> rows;

    /** 消息状态码*/
    private int code;

    /** 消息内容*/
    private String msg;

    public PageResult() {

    }

    public PageResult(long total, List<T> rows) {
        this.total = total;
        this.rows = rows;
    }

    public long getTotal() {
        return total;
    }

    public void setTotal(long total) {
        this.total = total;
    }

    public List<?> getRows() {
        return rows;
    }

    public void setRows(List<?> rows) {
        this.rows = rows;
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
}

 比如下面的 响应结果类,用了泛型T, 类上也需要带上

package com.tree.community.common.core.domain;


import java.io.Serializable;

/**
 * @Description 响应结果封装对象
 * @Author tree
 * @Date 2024/4/28 17:41
 */
public class BaseResponse<T> implements Serializable {
    private static final long serialVersionUID = -663626254744569433L;

    /**自定义状态码**/
    private String code;

    /**自定义描述**/
    private String message;

    /**返回的数据**/
    private T data;

    /**
     * 成功返回
     * @param data
     * @param <T>
     * @return
     */
    public static <T> BaseResponse<T> success(T data){
        BaseResponse<T> response = new BaseResponse<>();
        response.setCode(ResultCode.SUCCESS.getCode());
        response.setMessage(ResultCode.SUCCESS.getMessage());
        response.setData(data);
        return response;
    }

    /**
     * 失败返回
     * @param message
     * @param <T>
     * @return
     */
    public static <T> BaseResponse<T> fail(String message){
        BaseResponse<T> response = new BaseResponse<>();
        response.setCode(ResultCode.ERROR.getCode());
        response.setMessage(message);
        return response;
    }

    /**
     * 失败返回
     * @param code
     * @param message
     * @param <T>
     * @return
     */
    public static <T> BaseResponse<T> fail(String code, String message){
        BaseResponse<T> response = new BaseResponse<>();
        response.setCode(code);
        response.setMessage(message);
        return response;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }
}

深入理解泛型(经典详解):<T> T 和 T的使用以及public <E> List<E> get()泛型方法详解、类型擦除、通配符的使用、泛型类的应用、泛型之间的继承_泛型t-CSDN博客

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值