• 什么是泛型


    什么是泛型为什么要使用泛型

    泛型就是参数化类型

    泛型的作用

    减少重复代码

    像dao接口中存在样式雷同的代码:
    EmpDao:
    package com.aaa.gen.dao;
    import com.aaa.gen.entity.Emp;
    import java.util.List;
    /**
    * 员工管理dao接口
    DetpDao:
    */
    public interface EmpDao {
    /**
    * 查询所有的员工信息
    * @return
    */
    public List<Emp> listAll();
    /**
    * 保存员工信息
    * @param emp
    * @return
    */
    public int save(Emp emp);
    /**
    * 删除员工信息
    * @param emp
    * @return
    */
    public int delete(Emp emp);
    /**
    * 修改员工信息
    * @param emp
    * @return
    */
    public int update(Emp emp);
    /**
    * 根据主键查询 员工的信息
    * @param id
    * @return
    */
    public Emp find(Long id);
    }
    package com.aaa.gen.dao;
    import com.aaa.gen.entity.Dept;
    import java.util.List;
    /**
    * 部门管理dao接口
    */
    public interface DeptDao {
    /**
    有这么 多重复代码,肯定是不好的,我们应该使用一种范式提取出来。我们可以定义一个公共的BaseDao接口来
    解决这种问题:
    * 查询所有的部门信息
    * @return
    */
    public List<Dept> listAll();
    /**
    * 保存部门信息
    * @param dept
    * @return
    */
    public int save(Dept dept);
    /**
    * 删除部门信息
    * @param dept
    * @return
    */
    public int delete(Dept dept);
    /**
    * 修改部门信息
    * @param dept
    * @return
    */
    public int update(Dept dept);
    /**
    * 根据主键查询 部门的信息
    * @param id
    * @return
    */
    public Dept find(Long id);
    }
    package com.aaa.gen.common;
    import com.aaa.gen.entity.Dept;
    import java.util.List;
    public interface BaseDao<T> {
    /**
    * 查询所有的实体信息
    * @return
    */
    public List<T> listAll();
    然后针对某个特定多的接口比如EmpDao,我们可以让EmpDao继承BaseDao接口,同时指定泛型的类型:
    帮助我们提前发现一些程序的错误
    /**
    * 保存实体信息
    * @param t
    * @return
    */
    public int save(T t);
    /**
    * 删除实体信息
    * @param t
    * @return
    */
    public int delete(T t);
    /**
    * 修改实体信息
    * @param t
    * @return
    */
    public int update(T t);
    /**
    * 根据主键查询 实体的信息
    * @param id
    * @return
    */
    public T find(Long id);
    }
    package com.aaa.gen.dao;
    import com.aaa.gen.common.BaseDao;
    import com.aaa.gen.entity.Emp;
    import java.util.List;
    /**
    * 员工管理dao接口
    */
    public interface EmpDao extends BaseDao<Emp> {
    }

    帮助我们提前发现一些程序的错误
    package com.aaa.gen.test;
    import java.util.ArrayList;
    import java.util.List;定义泛型接口或者类
    定义泛型接口
    泛型接口在被实现的时候,如果实现类不再需要泛型,则需要指定泛型的具体类型:
    /**
    * 测试泛型
    */
    public class Test01 {
    /**
    * 打印list中所有的内容
    */
    public static void printList(List<String> list){
    for(int i=0;i<list.size();i++){
    String str = list.get(i);
    System.out.println(str);
    }
    }
    public static void main(String[] args) {
    List<String> list = new ArrayList<String>();
    list.add("Java");
    list.add("C#");
    list.add("python");
    list.add(123);
    Test01.printList(list);
    }
    }
    package com.aaa.gen;
    /**
    * 定义泛型接口list
    * 在接口后面使用<>表示,在<>可以定义泛型的形参,一般形参都使用单独的一个大写字母来表示
    * 多个发型的形参用逗号进行间隔 经常用的泛型的标识有T E
    *
    */
    public interface List<T> {
    /**
    * 迭代元素
    * @param t
    */
    public void iterator(T t);
    }如果实现类继续使用泛型,则可以不指定泛型的具体类型:
    定义泛型类
    package com.aaa.gen;
    /**
    * 如果实现类中不再使用泛型,则需要指定泛型的具体类型
    */
    public class ArrayList implements List<String> {
    @Override
    public void iterator(String s) {
    }
    }
    package com.aaa.gen;
    /**
    * 实现类中如果继续使用泛型 ,则不必指定泛型的具体类型
    * @param <T>
    */
    public class LinkedList<T> implements List<T>{
    @Override
    public void iterator(T t) {
    }
    }
    package com.aaa.gen;
    /**
    * 泛型类
    */
    public class Apple<T> {
    //声明泛型变量info
    private T info;
    public T getInfo() {
    return info;
    }
    public void setInfo(T info) {
    this.info = info;
    }
    }在使用的时候:
    泛型通配符
    需求:定义一个类,类中需要有打印一个字符串集合中的所有元素的方法,还需要有打印一个整数集合中的所有元
    素的方法
    package com.aaa.gen.test;
    import com.aaa.gen.Apple;
    /**
    * 测试泛型类
    */
    public class Test02 {
    public static void main(String[] args) {
    Apple<String> apple= new Apple<String>()apple.setInfo("红色");
    System.out.println(apple.getInfo());
    Apple<Integer> apple2= new Apple<Integer>();
    apple2.setInfo(10);
    System.out.println(apple2.getInfo());
    }
    }
    package com.aaa.gen.test;
    import java.util.List;
    public class Test03 {
    /**
    * 打印字符串集合中的所有的元素
    * @param list
    */
    public void printStr(List<String> list){
    for(String str : list){
    System.out.println(str);
    }
    }
    /**
    * 打印整数集合中的所有的元素
    * @param list
    */
    public void printInt(List<Integer> list){
    for(Integer num :list){
    System.out.println(num);
    }
    }我们发现所有打印的方法的代码结构上都是类似的,打印每种类型的变量的集合都需要再定义一个方法,这样做非
    常麻烦,有没有一个通用的方法可以解决这个问题?
    我们通过泛型通配符来解决这个问题,java提供一个方案,List 不是所有List<其他类型>的父类,但是List<?>可以
    理解为所有List<其他类型>的父类:
    /**
    * 打印小数集合中的所有的元素
    * @param list
    */
    public void printDouble(List<Double> list){
    for(Double num :list){
    System.out.println(num);
    }
    }
    }
    package com.aaa.gen.test;
    import java.util.ArrayList;
    import java.util.List;
    /**
    * 使用List<Object>来代替List<String>List<Double> List<Integer>
    */
    public class Test04 {
    /**
    * 打印所有的object对象
    * @param list
    */
    public void print(List<Object> list){
    for(Object obj : list){
    System.out.println(obj);
    }
    }
    public static void main(String[] args) {
    List<String> strList = new ArrayList<String>();
    strList.add("java");
    strList.add("c#");
    //String 是Object的子类,但是List<String> 还是不是List<Object>的子类了?不是了
    //我们还是希望List<Object>是List<String>或者是List<其他类型>的父类
    new Test04().print(strList);
    }
    }泛型通配符上限
    需求:声明一个方法,打印所有数字类型的集合中的元素
    package com.aaa.gen.test;
    import java.util.ArrayList;
    import java.util.List;
    /**
    * 使用List<?>来代替List<Object>
    */
    public class Test05 {
    /**
    * 打印所有的object对象
    * @param list
    */
    public static void print(List<?> list){
    for(Object obj : list){
    System.out.println(obj);
    }
    }
    public static void main(String[] args) {
    List<String> strList = new ArrayList<String>();
    strList.add("java");
    strList.add("c#");
    //可以理解为List<?>是所有List<其他类型>的父类
    new Test05().print(strList);
    List<Integer> intList = new ArrayList<Integer>();
    intList.add(1);
    intList.add(2);
    //可以理解为List<?>是所有List<其他类型>的父类
    new Test05().print(intList);
    }
    }
    package com.aaa.gen.test;
    import java.util.ArrayList;
    import java.util.List;
    /**
    * 泛型通配符上限
    */
    public class Test06 {
    /**
    * 打印所有的数字类型集合中的元泛型方法
    原先在使用泛型的时候,只把泛型定义在了类上或者接口上。泛型也可以只在一个方法上来使用。
    举例:声明一个泛型方法 合并两个list集合中的元素
    * @param list
    */
    public void printNum(List<? extends Number> list){
    for(Number n : list){
    System.out.println(n);
    }
    }
    public static void main(String[] args) {
    List<Integer> inStrs = new ArrayList<Integer>();
    inStrs.add(1);
    inStrs.add(2);
    //同List<Object>不是List<其他类型>的父类一样,List<Number>也不是List<Number的子类>的父类
    //如果要解决这种问题,就需要用到泛型通配符上限
    new Test06().printNum(inStrs);
    List<Double> doStrs = new ArrayList<Double>();
    doStrs.add(1D);
    doStrs.add(2D);
    new Test06().printNum(doStrs);
    List<String> strs = new ArrayList<String>();
    strs.add("abc");
    strs.add("def");
    new Test06().printNum(strs);
    }
    }
    package com.aaa.gen.test;
    import java.util.ArrayList;
    import java.util.List;
    /**
    * 泛型方法
    */
    public class Test07 {
    /**
    * 合并两个list集合
    * @param a
    * @param b
    */
    /* public static void join(List<String> a , List<String> b){
    for(String item :a){
    b.add(item);
    }
    }*/问题,如果b中的泛型类型声明成Object会报错:
    public static <T> void join(List<T> a , List<T> b){
    for(T item :a){
    b.add(item);
    }
    System.out.println(b);
    }
    public static void main(String[] args) {
    List<String> a = new ArrayList<String>();
    a.add("1");
    a.add("2");
    List<String> b = new ArrayList<String>();
    b.add("3");
    Test07.join(a,b);
    List<Integer> a1 = new ArrayList<Integer>();
    a1.add(1);
    a1.add(2);
    List<Integer> b1 = new ArrayList<Integer>();
    b1.add(3);
    Test07.join(a1,b1);
    }
    }怎么在不把Object改成String的前提下解决这种问题?泛型通配符下限
    需求:要返回最后一个添加的元素
    怎么样修改方法才能让返回值变成添加元素时的类型?
    package com.aaa.gen.test;
    import java.util.ArrayList;
    import java.util.List;
    /**
    * 泛型方法 发型通配符下限
    */
    public class Test08 {
    /**
    * 合并两个list集合 返回最后一个添加的元* @param a
    * @param b
    */
    /* public static void join(List<String> a , List<String> b){
    for(String item :a){
    b.add(item);
    }
    }*/
    public static <T> T join(List<? extends T> a , List<T> b){
    T last = null;
    for(T item :a){
    last = item;
    b.add(item);
    }
    System.out.println(b);
    return last;
    }
    public static void main(String[] args) {
    List<String> a = new ArrayList<String>();
    a.add("1");
    a.add("2");
    a.add("3");
    List<Object> b = new ArrayList<Object>()//返回值是什么类型,原先放置的时候类型是String类型,现在还能不能用String类型来接收返回值了?
    Object last = Test08.join(a,b);
    }
    }
    package com.aaa.gen.test;擦除
    把一个具有泛型信息的变量赋值给一个没有泛型信息的变量,泛型的信息会消失,这就叫做擦除。
    import java.util.ArrayList;
    import java.util.List;
    /**
    * 泛型方法 发型通配符下限
    */
    public class Test08 {
    /**
    * 合并两个list集合 返回最后一个添加的元* @param a
    * @param b
    */
    /* public static void join(List<String> a , List<String> b){
    for(String item :a){
    b.add(item);
    }
    }*/
    public static <T> T join(List<T> a , List<? super T> b){
    T last = null;
    for(T item :a){
    last = item;
    b.add(item);
    }
    System.out.println(b);
    return last;
    }
    public static void main(String[] args) {
    List<String> a = new ArrayList<String>();
    a.add("1");
    a.add("2");
    a.add("3");
    List<Object> b = new ArrayList<Object>()//返回值是什么类型,原先放置的时候类型是String类型,现在还能不能用String类型来接收返回值了?
    // Object last = Test08.join(a,b);
    //怎么样修改方法才能让返回值变成添加元素时的类型
    String last = Test08.join(a,b);
    }
    }
    package com.aaa.gen;
    /**
    * 泛型类
    */
    public class Apple<T> {测试:
    //声明泛型变量info
    private T info;
    public T getInfo() {
    return info;
    }
    public void setInfo(T info) {
    this.info = info;
    }
    }
    package com.aaa.gen.test;
    import com.aaa.gen.Apple;
    /**
    * 擦除
    */
    public class Test09 {
    public static void main(String[] args) {
    Apple<String> a1 = new Apple<String>();
    a1.setInfo("红色");
    String info = a1.getInfo();
    //把一个具有泛型信息的变量赋值给一个没有泛型信息的变量
    Apple a2=a1;
    //泛型类型信息会消失
    Object info1 = a2.getInfo();
    }
    }
  • 相关阅读:
    [转载] VsCode中使用Emmet神器快速编写HTML代码
    Hexo 博客部署到私有云服务器
    钉钉小程序通过 Canvas 将页面生成图片并保存到本地相册
    2021你应该了解的前端知识体系
    JavaScript 中的模块化
    vue中click事件方法不加括号则会将事件作为入参
    css:左右元素没对齐,调整子元素的vertical-align属性
    js通过宽高特征对图片进行分类
    配置服务器上的git仓库
    js获取当前设备信息
  • 原文地址:https://www.cnblogs.com/hph1728390/p/11005528.html
Copyright © 2020-2023  润新知