Spring深入---泛型的理解与使用

Spring深入---泛型的理解与使用,第1张

Spring深入---泛型的理解与使用

 

  注: 应该叫java 泛型

一、什么叫泛型

  1. 在程序编码中一些包含类型参数的类型,也就是说泛型的参数只可以代表类,不能代表个别对象。(这是当今较常见的定义)

  2. 在程序编码中一些包含参数的类。其参数可以代表类或对象等等。(现在人们大多把这称作模板)

-----百度百科

简单来说就是将参数的类型 也可以在使用的时候变化,不同的情况下使用不同的参数类型,这就好比你用榨汁机榨汁,当你放入西瓜的时候出来的是西瓜汁,放入葡萄的时候出来的是葡萄汁。过程都是一样的---先压碎,然后将汁倒入杯子中,虽然传过来的参数类型不同

二、为什么要使用泛型   1 确定传入的参数类型

  比如你向一个ArrayList集合中 添加了数字 和字符串,那么当你遍历这个集合的时候就会报错,所以一开始的时候就声明参数的类型

 2 复用代码

  还是集合类,如果不用泛型,那么你就要根据每个类型来判断处理逻辑甚至是一个类型一个处理类.但是,集合类,整体逻辑是一样的,就是对元素进行遍历, *** 作。

   List stringList = new ArrayList<>();
        stringList.add("黄土高坡");
        stringList.add("青藏高原");
        stringList.add("华北平原");
        
        List yearList = new ArrayList<>();
        yearList.add(2020);
        yearList.add(2021);

 再或者 返回给前端的结果就可以使用泛型进行封装

package com.example.demo.vo;

import com.example.demo.enums.CodeEnum;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;


@Data
public class ResultVo {

    @ApiModelProperty(value = "返回码")
    private String code;

    @ApiModelProperty(value = "返回的信息")
    private String msg;

    @ApiModelProperty(value = "返回的数据")
    private T data;

    public static  ResultVo success() {
        return build(CodeEnum.SUCCESS);
    }

    public static  ResultVo success(T data) {
        return build(CodeEnum.SUCCESS, data);
    }

    public static  ResultVo fail() {
        return build(CodeEnum.FAIl);
    }

    public static  ResultVo failed(String code, String msg) {
        ResultVo resultVo = new ResultVo<>();
        resultVo.setCode(code);
        resultVo.setMsg(msg);
        return resultVo;
    }
    
    public static  ResultVo build(String code, String msg, T data) {
        ResultVo resultVo = new ResultVo<>();
        resultVo.setMsg(msg);
        resultVo.setCode(code);
        resultVo.setData(data);
        return resultVo;
    }

    public static  ResultVo build(String code, String msg) {
        ResultVo resultVo = new ResultVo<>();
        resultVo.setCode(code);
        resultVo.setMsg(msg);
        return resultVo;
    }

    public static  ResultVo build(CodeEnum codeEnum) {
        return build(codeEnum, null);
    }

    public static  ResultVo build(CodeEnum codeEnum, T data) {
        ResultVo resultVo = new ResultVo<>();
        resultVo.setCode(codeEnum.getCode());
        resultVo.setData(data);
        resultVo.setMsg(codeEnum.getMsg());
        return resultVo;
    }
    
}

 使用 :

@RestController
public class TestController {


    @Autowired
    UserInfo userInfo;

    @GetMapping("/test")
    public ResultVo> test() {

        List stringList = new ArrayList<>();
        stringList.add("黄土高坡");
        stringList.add("青藏高原");
        stringList.add("华北平原");

        List yearList = new ArrayList<>();
        yearList.add(2020);
        yearList.add(2021);

        ResultVo> resultVo = ResultVo.success(stringList);
        return resultVo;

    }
}

结果:

 三 、泛型的种类与使用规则

(<>  这里面只是一个类型声明,声明了将要用到的类型)

   1、泛型类

    

public 类名 <类型标识,一般为T> {

  权限访问符 类型标识符 变量名称;
 
  权限访问符 类型标识符 方法名(参数,可以是T修饰的,也可以是普通类型)  {


    }
}

 比如:

public class ResultVo {

  public T data;


  public T getData() {
       return this.data;
  }


}

注意:泛型类目的是为了规范其内部的数据,使这个类能够重用。但是如果你不传入泛型,也一样可以用,不过这样就失去了泛型的意义。比如

        

   List testList =new ArrayList();
        testList.add("12313");
        testList.add(123);

idea都会提示你使用泛型

2 、泛型接口

  

public interface Generatic {
    T doSomeThing(T content);
}

 当类实现这个泛型接口的时候也要声明类型 

        

public class GeneraticImpl implements Generatic {

    private T data;


    @Override
    public T doSomeThing(T content) {
        return content;
    }
}

 使用:

       Generatic generatic = new GeneraticImpl<>();
        System.out.println(generatic.doSomeThing("12313"));
  3 、泛型方法

           泛型方法,可以不在泛型类中使用,也可以在普通类中使用。记住就是声明了一个类型,

          泛型方法就是一个声明了泛型变量的方法        

          比如这里,泛型类声明了一个类型T,然后泛型方法声明了一个类型E,这里的E可以是任意的符号,也可以是T。

public class ResultVo {

     private T data;

     private static  E build2(E data) {
        return data;
     }    

}
public class ResultVo {

     private T data;

     // 这里T 与类上T 两者不相同
     private  T build2(T data) {
        return data;
     }    

}

   ResultVo resultVo1 = new ResultVo<>();
        resultVo1.setMsg("1111");
        resultVo.testGeneric(111);

   

比较: 

public class ResultVo {

    
    public  E testGeneric(E data) {
        return data;
    }

    
    public   T getData() {
        return data;
    }





}
对于静态方法的处理:

        由于静态方法是跟着类走的,静态方法无法访问类上定义的泛型。所以当静态方法需要使用泛型的时候需要定义成泛型方法:

    private static  ResultVo build(CodeEnum codeEnum, T data) {
        System.out.println();
        ResultVo resultVo = new ResultVo<>();
        resultVo.setCode(codeEnum.getCode());
        resultVo.setData(data);
        resultVo.setMsg(codeEnum.getMsg());
        return resultVo;
    }

4 、通配符

 当你不清楚所要传入的数据的类型的范围时,可以使用通配符?,?和Number String 等被看成是一个实际的类型,你可以把它看成所有类型的父类,就像List 变成了List。不过只能使用Object方法,如果需要使用其他具体类型的函数,则需要进行判断然后强转。 

5 限制泛型的范围

          当我们知道泛型的需要被限制在哪些范围时,就可以使用

  // 使用的类型必须是Number的子类,也就是数字
public class Generic {

    private T data;
}

 使用:

     // 报错 Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number
    Generic generic =new Generic();
    // 正常
    Generic genericInteger =new Generic();

---看见了一个大神写的泛型

public static > T max (
 Listlist)
)

最后记住 :当这个类所记录的数据处理方式相同的时候,就可以使用泛型(所以C++称之为模板)

参考博文: java 泛型详解-绝对是对泛型方法讲解最详细的,没有之一 - little fat - 博客园

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/4746575.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-08
下一篇 2022-11-08

发表评论

登录后才能评论

评论列表(0条)

保存