泛型用的好,下班走得早

简介:

泛型方法和类允许程序员编写高级化的单个方法或类,以用于不同的类型。

泛型方法和类允许程序员编写高级化的单个方法或类,以用于不同的类型。

我们每天都在使用它们,例如List ,Stream ,Map …

泛型类是普通类,其类名后跟一个类型参数部分。这些类称为参数化类或参数化类型,因为它们接受一个或多个参数。

特征:

  • 类型安全:泛型中只能容纳一种类型的对象。
  • 不需要类型转换:无需类型转换对象。
  • 编译时检查:在编译时进行检查,因此在运行时不会发生此问题。好的编程策略表明,在编译时处理问题比运行时要好得多。

类型参数命名约定:

  • T type
  • E element
  • K Key
  • N Number
  • V value

泛型通配符:

我们知道 ? 是通配符,它表示任何类型。如果我们写<? extends Number>,我们接受Number的任何子类,例如Integer,Float和double。

我们可以使用通配符作为参数,字段,返回类型或局部变量的类型。但是,不允许将通配符用作泛型方法调用,泛型类实例创建或超类型的类型参数。

通用类示例:

public class Response<T> {
 private List<T> data;
 private Integer page;
 private Integer elements;
}

在第一个简单示例中,我们创建了一个通用类Response,将用于返回分页的结果。我们不需要做魔术,也不必创建其他类。

如何写更少的代码?

尽管泛型在库中使用非常广泛,但是我看到很少有程序员使用泛型来泛化代码,例如,您有多少次看到控制器,服务和存储库几乎在做同样的事情?

在介绍完之后,我希望您展示一个简单的示例,说明如何编写一次性代码并在多个类中使用它。

一个简单的项目

在此示例中,我想向您展示如何定义BaseService和GeneralRepository来处理Java服务中的常见操作。

BaseEntity.java

@Data
@AllArgsConstructor
@NoArgsConstructor
public class BaseEntity {
    @Id
    protected String id;
    protected String tenantId;
    protected Date creationDate;
    protected Date updateDate;
}

我们正在创建一个简单的类,该类在我们的类中包含commons属性,下一个代码段将很有必要。

BaseRepository

@Repository
public interface GenericRepository<E extends BaseEntity> extends ReactiveCrudRepository<E, String> {
    Mono<Void> deleteByIdAndTenantId(String id, String tenantId);
    Mono<E> findFirstByIdAndTenantId(String id, String tenantId);
}

这是基本存储库,其中包含对我们的BaseEntity类的子类的常见查询。

BaseService

@Service
@Slf4j
public class BaseService<E extends BaseEntity> {

    @Autowired
    protected GenericRepository<E> generalRepo;

    public Mono<E> findEnitity(String entityId, String tenantId) {
        return generalRepo.findFirstByIdAndTenantId(entityId,tenantId);
    }

    public Mono<Void> delete(String entityId, String tenantId) {
        return findEnitity(entityId, tenantId)
                .switchIfEmpty(Mono.error(new NotFoundException(ITEM_NOT_FOUND)))
                .flatMap(e -> generalRepo.deleteByIdAndTenantId(e.getId(),e.getTenantId()));
    }
    
    public Mono<E> saveEntity(String tenantId, E entity) {
        entity.setTenantId(tenantId);
        return generalRepo.save(entity);
    }

    public Mono<E> updateEntity(String entityId, String tenantId,E entity) {
        return findEnitity(entityId,tenantId)
                .map(u -> saveEntity(tenantId,entity))
                .switchIfEmpty(Mono.error(new Exception(ITEM_NOT_FOUND)))
                .flatMap(m -> m);
    }
}

所有服务将继承BaseService继承继承的保存,更新,查找和删除方法,这些方法执行通用操作以将我们的数据持久保存在数据库中。显然,这段代码非常简单,您可以编写一种处理分页请求的方法,在执行插入/更新之前添加检查。

BaseController

public class BaseController<E extends BaseEntity> {

    @Autowired
    private BaseService<E> baseService;

    @PostMapping("/save")
    public Mono<E> save(Authentication auth,
                        @RequestBody E entity) {
        return baseService.save(getTenant(auth),entity);
    }
    
}

让我们以允许在多个控制器之间共享公共端点的BaseController结束该示例。

总结

因此,我们对泛型进行了一些小小的更新,并看到了如何编写更少的代码来使多个类之间的通用操作更加温和。

目录
相关文章
|
运维 监控 安全
幻兽帕鲁服务器搭建保姆级教程,阿里云服务器部署指南。
本文更新阿里云服务器部署幻兽帕鲁保姆级教程,傻瓜式指南,上篇文章写了腾讯云服务器搭建幻兽帕鲁的教程,对《幻兽帕鲁》这类可能对内存有较高要求的游戏,阿里云这里同腾讯云一样推荐至少16GB以上的内存配置,并搭配高性能CPU以及充足的带宽资源,确保游戏运行流畅不卡顿。
|
8月前
|
Unix Linux 编译器
windows下和linux下cmake的规则有区别吗
通过合理使用CMake的条件逻辑和平台特定的配置选项,开发者可以编写更加灵活和健壮的CMake脚本,确保项目在Windows和Linux上的一致性和可移植性。
396 76
|
7月前
|
关系型数据库 MySQL Linux
在Linux环境下备份Docker中的MySQL数据并传输到其他服务器以实现数据级别的容灾
以上就是在Linux环境下备份Docker中的MySQL数据并传输到其他服务器以实现数据级别的容灾的步骤。这个过程就像是一场接力赛,数据从MySQL数据库中接力棒一样传递到备份文件,再从备份文件传递到其他服务器,最后再传递回MySQL数据库。这样,即使在灾难发生时,我们也可以快速恢复数据,保证业务的正常运行。
332 28
|
5月前
|
人工智能 Java 程序员
程序员副业搞钱新姿势!晒完整工程代码赢万元好礼
飞算JavaAI炫技赛重磅回归!展示解决复杂业务场景的完整工程代码,赢取万元现金大奖,让技术实力被业界看见。通过比赛,你的作品将成为最佳简历,吸引高质项目与合作,解锁长期副业可能。借助飞算AI工具提效,掌握未来竞争力,拓展人脉圈链接更多资源。程序员们,立即参赛,用代码开启“搞钱”新征途!
|
12月前
|
存储 缓存 监控
后端开发中的缓存机制:深度解析与最佳实践####
本文深入探讨了后端开发中不可或缺的一环——缓存机制,旨在为读者提供一份详尽的指南,涵盖缓存的基本原理、常见类型(如内存缓存、磁盘缓存、分布式缓存等)、主流技术选型(Redis、Memcached、Ehcache等),以及在实际项目中如何根据业务需求设计并实施高效的缓存策略。不同于常规摘要的概述性质,本摘要直接点明文章将围绕“深度解析”与“最佳实践”两大核心展开,既适合初学者构建基础认知框架,也为有经验的开发者提供优化建议与实战技巧。 ####
|
12月前
|
网络协议 自动驾驶 物联网
计算机网络的发展
本文概述了计算机网络从20世纪60年代的雏形到现代互联网的发展历程,包括ARPANET的创建、TCP/IP协议的标准化、DNS系统的引入、万维网的诞生、宽带和无线网络的兴起,以及移动互联网、云计算、物联网、区块链和自动驾驶技术的最新进展。
685 1
|
缓存 前端开发 JavaScript
"面试通关秘籍:深度解析浏览器面试必考问题,从重绘回流到事件委托,让你一举拿下前端 Offer!"
【10月更文挑战第23天】在前端开发面试中,浏览器相关知识是必考内容。本文总结了四个常见问题:浏览器渲染机制、重绘与回流、性能优化及事件委托。通过具体示例和对比分析,帮助求职者更好地理解和准备面试。掌握这些知识点,有助于提升面试表现和实际工作能力。
241 1
|
弹性计算 负载均衡 数据库
阿里云轻量应用服务器全面解析:收费标准、产品优势及适用场景
在云计算领域,阿里云凭借其强大的技术实力和丰富的产品线,为用户提供了一系列高效、便捷的云服务器产品。其中,轻量应用服务器(Simple Application Server)作为面向个人开发者、中小企业等用户的入门级云产品,凭借其易用性、高性价比以及一站式服务体验,受到了广泛的欢迎。本文将全面解析阿里云轻量应用服务器的收费标准、产品优势以及适用场景,帮助用户更好地了解和选择这一产品。
阿里云轻量应用服务器全面解析:收费标准、产品优势及适用场景
|
JavaScript
箭头函数与普通函数(function)的区别
箭头函数是ES6引入的新语法,相比传统函数表达式更简洁,且没有自己的this、arguments、super或new.target绑定,而是继承自外层作用域。这使得箭头函数在处理回调和闭包时更加灵活方便。
|
负载均衡 网络协议 应用服务中间件
Nginx配置以及热升级
Nginx配置以及热升级
239 7