Java基础-泛型

Posted rainsherry007

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java基础-泛型相关的知识,希望对你有一定的参考价值。

一、泛型定义

        泛型即“参数化类型”,就是将类型由原来具体的类型参数化,类似于方法中的变量参数,然后使用的时候传入具体的参数。这种参数类型可以用在类、接口和方法中,分别被称为泛型类、泛型接口和泛型方法。常见的泛型类型变量:

  • E(Element):元素,多用于 java 集合框架
  • K(Key):关键字
  • N(Number):数字
  • T(Type):类型
  • V(Value):值

二、使用泛型原因  

  • 提高可读性
  • 代码复用
  • 使 ClassCastException 这种错误在编译期就可以检测出来

三、泛型使用规范

  • 不能实例化泛型类
  • 静态变量或方法不能引用泛型类型变量,但是静态泛型方法是可以的
  • 基本类型无法作为泛型类型
  • 无法使用 instanceof 关键字或 == 判断泛型类的类型
  • 泛型类的原生类型与所传递的泛型无关,无论传递什么类型,原生类是一样的
  • 泛型数组可以声明但无法实例化
  • 泛型类不能继承 Exception 或者 Throwable
  • 不能捕获泛型类型限定的异常但可以将泛型限定的异常抛出 

四、通配符类型

  • <? extends Parent> 指定了泛型类型的上限
  • <? super Child> 指定了泛型类型的下届
  • <?> 指定了没有限制的泛型类型

五、泛型擦除

        泛型是提供给 javac 编译器使用的,用于限定集合的输入类型,让编译器在源代码级别上,即挡住向集合中插入非法数据。但编译器编译完带有泛形的 java 程序后,生成的 class 文件中将不再带有泛形信息,使程序运行效率不受到影响,这个过程称之为 “擦除”。 

六、泛型类demo

场景:数据量比较小,几百条数据,数据结构不固定的场景(数据结构不固定可以用ElasticSearch或者Mongo,但是数据量比较小,有点浪费)可以通过泛型类的方法使用mysql

以H5素材为例:

数据库设计:

CREATE TABLE MaterialInfo (
  id int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '素材id',
  materialType tinyint(4) NOT NULL DEFAULT '1' COMMENT '素材类型',
  schemeType tinyint(4) NOT NULL DEFAULT '0' COMMENT '方案类型',
  planName varchar(256) NOT NULL DEFAULT '' COMMENT '计划名称',
  otherField text COMMENT '素材其他字段',
  creator varchar(20) NOT NULL DEFAULT '' COMMENT '创建人',
  createTime timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  updateTime timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`id`)
) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8mb4 COMMENT = '素材详情表';

代码:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * @description
 * @Author: rainsherry
 * @Date: 2022/8/5 下午3:17
 */
@Controller
@RequestMapping("/test")
public class MaterialAction 

    @Autowired
    private MaterialService materialService;

    /**
     * 查询素材接口
     *
     * @param id
     * @return
     */
    @RequestMapping("/getMaterial")
    public MaterialResult getMaterial(Integer id) 
        return materialService.getMaterial(id);
    

    /**
     * 新增素材
     *
     * @param param
     * @return
     */
    @RequestMapping("/insertMaterial")
    public String insertMaterial(@RequestBody MaterialParam param) 
        return materialService.insertMaterial(param);
    

import java.io.Serializable;
import java.util.Date;
import java.util.StringJoiner;

/**
 * @description
 * @Author: rainsherry
 * @Date: 2022/8/4 下午6:00
 */
public class MaterialParam<T> implements Serializable 

    /**
     * 素材id
     */
    private long id;

    /**
     * 素材类型
     * @link MaterialTypeEnum
     */
    private Integer materialType;

    /**
     * 方案类型
     * @link SchemeTypeEnum
     */
    private Integer schemeType;

    /**
     * 计划名称
     */
    private String planName;

    /**
     * 创建人
     */
    private String creator;

    private T entity;

    public T getEntity() 
        return entity;
    

    public void setEntity(T entity) 
        this.entity = entity;
    


    public long getId() 
        return id;
    

    public void setId(long id) 
        this.id = id;
    

    public Integer getMaterialType() 
        return materialType;
    

    public void setMaterialType(Integer materialType) 
        this.materialType = materialType;
    

    public Integer getSchemeType() 
        return schemeType;
    

    public void setSchemeType(Integer schemeType) 
        this.schemeType = schemeType;
    

    public String getPlanName() 
        return planName;
    

    public void setPlanName(String planName) 
        this.planName = planName;
    

    public String getCreator() 
        return creator;
    

    public void setCreator(String creator) 
        this.creator = creator;
    


import java.io.Serializable;
import java.util.Date;
import java.util.StringJoiner;

/**
 * @description
 * @Author: rainsherry
 * @Date: 2022/8/5 下午6:13
 */
public class MaterialResult<T> implements Serializable 

    /**
     * 素材id
     */
    private long id;

    /**
     * 素材类型
     * @link MaterialTypeEnum
     */
    private Integer materialType;

    /**
     * 方案类型
     * @link SchemeTypeEnum
     */
    private Integer schemeType;

    /**
     * 计划名称
     */
    private String planName;

    /**
     * 创建人
     */
    private String creator;

    /**
     * 创建时间
     */
    private Date createTime;

    /**
     * 更新时间
     */
    private Date updateTime;

    private T entity;

    public long getId() 
        return id;
    

    public void setId(long id) 
        this.id = id;
    

    public Integer getMaterialType() 
        return materialType;
    

    public void setMaterialType(Integer materialType) 
        this.materialType = materialType;
    

    public Integer getSchemeType() 
        return schemeType;
    

    public void setSchemeType(Integer schemeType) 
        this.schemeType = schemeType;
    

    public String getPlanName() 
        return planName;
    

    public void setPlanName(String planName) 
        this.planName = planName;
    

    public String getCreator() 
        return creator;
    

    public void setCreator(String creator) 
        this.creator = creator;
    

    public Date getCreateTime() 
        return createTime;
    

    public void setCreateTime(Date createTime) 
        this.createTime = createTime;
    

    public Date getUpdateTime() 
        return updateTime;
    

    public void setUpdateTime(Date updateTime) 
        this.updateTime = updateTime;
    

    public T getEntity() 
        return entity;
    

    public void setEntity(T entity) 
        this.entity = entity;
    

import org.apache.commons.collections.CollectionUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.beans.BeanUtils;

/**
 * @description
 * @Author: rainsherry
 * @Date: 2022/8/5 下午3:19
 */
@Service
public class MaterialService 

    private static final Logger LOGGER = LoggerFactory.getLogger(MaterialService.class);

    @Autowired
    private MaterialInfoMapper materialInfoMapper;

    @Override
    public String insertMaterial(MaterialParam param) 
        LOGGER.debug("MaterialService insertMaterial param is ", param);
        MaterialInfo info = new MaterialInfo();
        BeanUtils.copyProperties(param, info);
        info.setOtherField(JSON.toJSONString(param.getEntity()));
        return materialInfoMapper.insert(info) > 0 ? "成功" : "失败";
    

    @Override
    public MaterialResult getMaterialList(Long id) 
        MaterialInfo info = materialInfoMapper.selectById(id);
        MaterialResult result = new MaterialResult();
        BeanUtils.copyProperties(info, result);
        if (result != null) 
            result.setEntity(JSONObject.parse(info.getOtherField()));
        
        return result;
    

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.springframework.stereotype.Component;

/**
 * @description
 * @Author: rainsherry
 * @Date: 2022/8/5 下午4:51
 */
@Component
public interface MaterialInfoMapper extends BaseMapper<MaterialInfo> 

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;

import java.io.Serializable;
import java.util.Date;
import java.util.StringJoiner;

/**
 * @description
 * @Author: rainsherry
 * @Date: 2022/8/5 下午4:46
 */
@TableName("MaterialInfo")
public class MaterialInfo implements Serializable 

    /**
     * 素材id
     */
    @TableId(value = "id", type = IdType.INPUT)
    private long id;

    /**
     * 素材类型
     * @link MaterialTypeEnum
     */
    @TableField("materialType")
    private Integer materialType;

    /**
     * 方案类型
     * @link SchemeTypeEnum
     */
    @TableField("schemeType")
    private Integer schemeType;

    /**
     * 计划名称
     */
    @TableField("planName")
    private String planName;

    /**
     * 创建人
     */
    private String creator;

    /**
     * 创建时间
     */
    @TableField("createTime")
    private Date createTime;

    /**
     * 更新时间
     */
    @TableField("updateTime")
    private Date updateTime;

    /**
     * 其他素材字段
     */
    @TableField("otherField")
    private String otherField;

    public long getId() 
        return id;
    

    public void setId(long id) 
        this.id = id;
    

    public Integer getMaterialType() 
        return materialType;
    

    public void setMaterialType(Integer materialType) 
        this.materialType = materialType;
    

    public Integer getSchemeType() 
        return schemeType;
    

    public void setSchemeType(Integer schemeType) 
        this.schemeType = schemeType;
    

    public String getPlanName() 
        return planName;
    

    public void setPlanName(String planName) 
        this.planName = planName;
    

    public String getCreator() 
        return creator;
    

    public void setCreator(String creator) 
        this.creator = creator;
    

    public Date getCreateTime() 
        return createTime;
    

    public void setCreateTime(Date createTime) 
        this.createTime = createTime;
    

    public Date getUpdateTime() 
        return updateTime;
    

    public void setUpdateTime(Date updateTime) 
        this.updateTime = updateTime;
    

    public String getOtherField() 
        return otherField;
    

    public void setOtherField(String otherField) 
        this.otherField = otherField;
    


以上是关于Java基础-泛型的主要内容,如果未能解决你的问题,请参考以下文章

Java 泛型上限规则不会破坏 Liskov 替换吗? [复制]

java泛型上限下限,通配符

java泛型上限下限,通配符

JAVA-初步认识-常用对象API(集合框架-泛型-泛型限定-上限)

Java 泛型通配符上限和通配符下限(正在整理)

JAVA泛型之<? extends T>:(通配符上限)和<? super T>(通配符下限)