网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
序言
说到Java泛型,大家应该都不陌生。常用于限制Java各种容器的数据类型。它是Java JDK 1.5后增加的特性,所以已经是一个比较老的特性了。这里写这篇文章主要目的是为了给大家复习泛型的知识点。
Java泛型(Generic)
介绍
泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。
作用
Java泛型的主要作用有:
- 类型安全:编译时强类型检查,编译器可以直接验证类型假设。
- 消除强制类型转换:消除代码中的许多强制类型转换,使得代码可读性更高,减少出错机会。
- 提高代码复用性:泛型可以避免一些有相同特性且重复的代码。
至于泛型是否会带来性能问题,这个说法不一。但泛型是一个编译时的功能,增强代码可读性、复用性的收益远大于泛型进行类型转换的影响。
应用场景
泛型类
package com.hust.zhang.generic;
import lombok.AllArgsConstructor;
import lombok.Getter;
@AllArgsConstructor
public class GenericClass<T> {
@Getter
private T item;
}
定义一个Java泛型类,泛型类中的成员变量的类型可以通过类对象实例化时进行约束,测试如下,
public class GenericTest {
public static void main(String[] args) {
GenericClass<String> generic1 = new GenericClass<>("item");
GenericClass<Long> generic2 = new GenericClass<>(123L);
System.out.println(generic1.getItem().getClass().getName());//java.lang.String
System.out.println(generic2.getItem().getClass().getName());//java.lang.Long
}
}
泛型接口
Java泛型接口和泛型类基本类似,用过Mybatis或者Mybaits-plus的同学应该都知道使用代码自动生成工具生成的Mapper文件里BaseMapper就是一个泛型接口,把它作为示例。
package com.baomidou.mybatisplus.core.mapper;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.annotations.Param;
public interface BaseMapper<T> extends Mapper<T> {
int insert(T entity);
int deleteById(Serializable id);
int deleteByMap(@Param("cm") Map<String, Object> columnMap);
int delete(@Param("ew") Wrapper<T> wrapper);
int deleteBatchIds(@Param("coll") Collection<? extends Serializable> idList);
int updateById(@Param("et") T entity);
int update(@Param("et") T entity, @Param("ew") Wrapper<T> updateWrapper);
T selectById(Serializable id);
List<T> selectBatchIds(@Param("coll") Collection<? extends Serializable> idList);
List<T> selectByMap(@Param("cm") Map<String, Object> columnMap);
T selectOne(@Param("ew") Wrapper<T> queryWrapper);
Integer selectCount(@Param("ew") Wrapper<T> queryWrapper);
List<T> selectList(@Param("ew") Wrapper<T> queryWrapper);
List<Map<String, Object>> selectMaps(@Param("ew") Wrapper<T> queryWrapper);
List<Object> selectObjs(@Param("ew") Wrapper<T> queryWrapper);
IPage<T> selectPage(IPage<T> page, @Param("ew") Wrapper<T> queryWrapper);
IPage<Map<String, Object>> selectMapsPage(IPage<T> page, @Param("ew") Wrapper<T> queryWrapper);
}
然后数据库表的接口继承BaseMapper,各个数据库表接口的实现继承ServiceImpl类就具备了增删改查的基本功能了。
/**
* IService 实现类( 泛型:M 是 mapper 对象,T 是实体 , PK 是主键泛型 )
*/
public class ServiceImpl<M extends BaseMapper<T>, T> implements IService<T> {
protected Log log = LogFactory.getLog(getClass());
@Autowired
protected M baseMapper;
@Override
public M getBaseMapper() {
return baseMapper;
}
//... 省略 ...
}
泛型方法
上面的栗子里其实包含了泛型类、泛型接口和泛型方法,下面再举一个单纯的泛型方法,直接打印泛型的数据类型。
private static <T> void printGeneric(T t){
System.out.println(t.getClass().getName());
}
实际应用
下面看一个实际应用,比如以太专线和以太专网的公共属性类为以太连接。
以太连接父类:
@Data
public class EthConnection {
private String attribute;
}
以太专线子类:
@Data
public class ELineConnection extends EthConnection{
private String uuid;
}
以太专网子类:
@Data
public class ELanConnection extends EthConnection{
private String uuid;
}
比如我想对以太专线和以太专网子类传入它们共有的属性,那么我得像下面这么做,
public class GenericDemo {
public static void main(String[] args) {
String attr = "commonAttribute";
List<ELanConnection> eLanConnectionList = buildELanConnection(attr);
List<ELineConnection> eLineConnectionList = buildELineConnection(attr);
![img](https://img-blog.csdnimg.cn/img_convert/ce376b5c672214660828751c687d728d.png)
![img](https://img-blog.csdnimg.cn/img_convert/2fc3019cb274736bbd8df083cd121c83.png)
![img](https://img-blog.csdnimg.cn/img_convert/b7efc09e92cc6c0dc543c0dc5acc04ef.png)
**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!**
**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**
**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618658159)**
V-1715624308074)]
**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!**
**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**
**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618658159)**