你有没有使用过这些编程骚操作(一)- Lombok(Part B)(下)

简介: 你有没有使用过这些编程骚操作(一)- Lombok(Part B)

七、Lombok中 @Slf4j 日志注解使用

@Slf4j可以简化日志的引入,用于代替以下这段代码

private static final Logger logger = LoggerFactory.getLogger(Xxx.class);
复制代码

c1989b2bc0504c0abb9af82cfaae3081_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

上图中slf4j和commons-loggin都是日志规范;logback jdk-logging log4j log4j2都是日志实现。想要做到日志统一就需要用到桥接包,也可以参考SLF4J官网给出的解决方案

@Slf4j注解

首先添加相关的Jar包支持

<!-- 日志规范 -->
<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-api</artifactId>
  <version>1.7.36</version>
</dependency>
<!-- 日志实现 -->
<dependency>
  <groupId>ch.qos.logback</groupId>
  <artifactId>logback-classic</artifactId>
  <version>1.2.11</version>
  <scope>test</scope>
</dependency>
复制代码

在test包中新建一个LogAnnotationTest测试类,使用@Slf4j注解

@Slf4j
public class LogAnnotationTest {
    @Test
    public void testLogger(){
        log.error("这是输出的日志信息");
    }
}
复制代码

执行testLogger方法

1adb51742b4347e9b15c34dfcd94bbd1_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

查看编译后的文件

26bccb42fb0d47279ea5052ab784461d_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

自动帮我们生成了一个构造方法,并且定义了一个log属性,这个属性是slf4j的LoggerFactory通过调用getLogger方法返回的,并且通过接口来输出日志,这也是比较推荐的方法

八、对象创建 @Builder注解 与 @Singular注解

@Builder注解

@Builder注解的作用将对象的创建和使用完全分割开来,对象的创建只能用@Builder来创建,创建完成之后,对象不可变,可以使用这个对象,但是不能修改,这也符合高耦合低内聚的原则。

在test包下新建一个BuilderAnnotationTest测试类

@Builder
@Data
public class BuilderAnnotationTest {
    private static String staticField;
    private final String finalField;
    private final String initFinalField = "已经初始化的字段";
    private String field;
    public static void main(String[] args) {
        // 创建BuilderAnnotationTest对象
        // 首先调用builder方法创建一个可以链式赋值的对象
        BuilderAnnotationTest builderAnnotationTest = BuilderAnnotationTest.builder()
                                                      .finalField("手动赋值字段finalField")
                                                      // 其他属性不能赋值
                                                      .field("手动赋值field")
                                                      // 创建对象,此时创建的对象是不可变的
                                                      .build();
        System.out.println(builderAnnotationTest);
    }
}
复制代码

执行main方法

8201ef220b934434b085cad2c43997b3_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

根据控制台的输出说明可以成功创建对象

查看target目录下编译后的代码

@Builder注解帮我们创建了一个构造方法

image.png

定义了一个builder方法来创建对象BuilderAnnotationTestBuilder 内部类

image.png

其中getter/setter/hashcode/equals方法都是@Data注解生成的

@Builder注解生成的内部类

image.png

这个类包含两个属性和一个空参构造方法,以及几个以属性名为方法名的方法,用于给属性赋值,还包含了toString方法以及build方法,build方法就是用于创建BuilderAnnotationTest对象的方法,使用了内部的两个属性,调用BuilderAnnotationTest上面的包含两个参数的构造方法来创建对象

总结下来就是创建一个内部类,用来持久化需要赋值的属性的属性值,并且使用这些属性通过调用构造方法来创建一个不可变的对象,对象创建过程对外是不可见的,所以对象是不可修改的

给普通属性赋值,再次调用main方法,查看创建出来的对象的普通属性的值是否会变化

image.png

普通属性的初始值创建对象的时候不会带过来;默认的值如果不手动赋值,是不会带过来的

@Singular注解

@Singular注解配合@Builder注解使用,可以简化集合类型的操作 给BuilderAnnotationTest类增加一个List列表属性,测试@Singular如何简化操作

private List<String> listFields;
复制代码

修改main方法,手动给list属性赋值

public static void main(String[] args) {
    // 创建BuilderAnnotationTest对象
    // 首先调用builder方法创建一个可以链式赋值的对象
    BuilderAnnotationTest builderAnnotationTest = BuilderAnnotationTest.builder()
                                                  .finalField("手动赋值字段finalField")
                                                  // 其他属性不能赋值
                                                  .field("手动赋值field")
                                                  .listFields(new ArrayList<>())
                                                  // 创建对象,此时创建的对象是不可变的
                                                  .build();
复制代码

执行main方法

image.png

列表属性上添加@Singular注解

@Singular
private List<String> listFields;
复制代码

再次手动给列表属性赋值

image.png

有两个方法可以进行赋值

image.png

@Singular注解可以对集合属性生成单独追加单个元素的方法,并且可以连续追加。执行测试

image.png

listField方法赋值成功。也可以连续调用listField赋值多个元素到列表中

image.png

执行测试

image.png

说明连续调用赋值也是成功的

查看target目录下生成的class代码

image.png

image.png

listField方法可以接收一个单独的String类型参数,并将该参数加入到初始化号的listFields 中,相当于帮我们解决了集合为空的时候如何填入第一个元素

image.png

还生成了一个clearListFields方法,当集合不为空的时候清除集合

调用build方法的时候会判断集合是否为空,集合为空的时候会创建一个空的list赋值给集合属性,如果只有一个元素的时候,会创建一个singletonList赋值给列表,最后创建一个不可变的集合赋值给列表属性


相关实践学习
通过日志服务实现云资源OSS的安全审计
本实验介绍如何通过日志服务实现云资源OSS的安全审计。
相关文章
|
4月前
|
Java
如何在Java中进行多线程编程
Java多线程编程常用方式包括:继承Thread类、实现Runnable接口、Callable接口(可返回结果)及使用线程池。推荐线程池以提升性能,避免频繁创建线程。结合同步与通信机制,可有效管理并发任务。
233 6
|
4月前
|
IDE Java 编译器
java编程最基础学习
Java入门需掌握:环境搭建、基础语法、面向对象、数组集合与异常处理。通过实践编写简单程序,逐步深入学习,打牢编程基础。
299 1
|
5月前
|
SQL Java 数据库
2025 年 Java 从零基础小白到编程高手的详细学习路线攻略
2025年Java学习路线涵盖基础语法、面向对象、数据库、JavaWeb、Spring全家桶、分布式、云原生与高并发技术,结合实战项目与源码分析,助力零基础学员系统掌握Java开发技能,从入门到精通,全面提升竞争力,顺利进阶编程高手。
1051 0
|
4月前
|
安全 前端开发 Java
从反射到方法句柄:深入探索Java动态编程的终极解决方案
从反射到方法句柄,Java 动态编程不断演进。方法句柄以强类型、低开销、易优化的特性,解决反射性能差、类型弱、安全性低等问题,结合 `invokedynamic` 成为支撑 Lambda 与动态语言的终极方案。
221 0
|
6月前
|
安全 Java 数据库连接
2025 年最新 Java 学习路线图含实操指南助你高效入门 Java 编程掌握核心技能
2025年最新Java学习路线图,涵盖基础环境搭建、核心特性(如密封类、虚拟线程)、模块化开发、响应式编程、主流框架(Spring Boot 3、Spring Security 6)、数据库操作(JPA + Hibernate 6)及微服务实战,助你掌握企业级开发技能。
894 3
|
5月前
|
Java 开发者
Java并发编程:CountDownLatch实战解析
Java并发编程:CountDownLatch实战解析
517 100
|
5月前
|
IDE 安全 Java
Lombok 在企业级 Java 项目中的隐性成本:便利背后的取舍之道
Lombok虽能简化Java代码,但其“魔法”特性易破坏封装、影响可维护性,隐藏调试难题,且与JPA等框架存在兼容风险。企业级项目应优先考虑IDE生成、Java Records或MapStruct等更透明、稳健的替代方案,平衡开发效率与系统长期稳定性。
410 115
|
5月前
|
算法 Java
Java多线程编程:实现线程间数据共享机制
以上就是Java中几种主要处理多线程序列化资源以及协调各自独立运行但需相互配合以完成任务threads 的技术手段与策略。正确应用上述技术将大大增强你程序稳定性与效率同时也降低bug出现率因此深刻理解每项技术背后理论至关重要.
430 16
|
5月前
|
NoSQL Java 关系型数据库
超全 Java 学习路线,帮你系统掌握编程的超详细 Java 学习路线
本文为超全Java学习路线,涵盖基础语法、面向对象编程、数据结构与算法、多线程、JVM原理、主流框架(如Spring Boot)、数据库(MySQL、Redis)及项目实战等内容,助力从零基础到企业级开发高手的进阶之路。
439 2
|
6月前
|
安全 算法 Java
Java泛型编程:类型安全与擦除机制
Java泛型详解:从基础语法到类型擦除机制,深入解析通配符与PECS原则,探讨运行时类型获取技巧及最佳实践,助你掌握泛型精髓,写出更安全、灵活的代码。