优雅的Java工具库Lombok

优雅的Java工具库Lombok

最近在公司的项目中看到了对于Lombok的应用,通过@Data注解标注POJO,省略了大量的getter/setter代码,原先冗长的POJO在瘦身之后直接变得干净、清爽,程序员再也不需要去关注那些长长的方法,只需要集中注意力于字段field之中

Lombok简介

Lombok是一个非常实用的Java工具库,有效地简化Java代码的冗长。它通过注解如@Data可以直接为Java bean在编译期动态地生成字段的getter/setter方法,使用注解@NoArgsConstructor 和@AllArgsConstructor 为Java bean添加无参构造器和有参构造器,甚至可以在Java代码中使用val和var声明一个动态变量,而无需再指定具体的变量类型,区别只是val声明的变量为final。Lombok还提供了delombok供生成Javadoc,delombok在运行时会将注解@Data转换成getter/setter方法,然后移除@Data注解,如果哪天不再需要Lombok,也只需要简单运行delombok即可。Lombok的构建支持maven和gradle,同时eclipse、myeclipse和idea等主流IDE也都和lombok兼容,所以可以放心大胆地使用Lombok,不用担心IDE的编译检查问题。

Lombok栗子

Eclipse安装Lombok支持

官网Lombok https://projectlombok.org/download 下载jar包或者通过构建工具maven,gradle下载jar包

双击jar包,jar包内的安装器会自动运行寻找eclipse

点击【Install/Update】

引入Lombok依赖

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.2</version>
        <scope>provided</scope>
    </dependency>

Lombok注解使用

Lombok的注解分为稳定版本和试验版本,这里主要介绍稳定版本,因为试验版本的支持目前和IDE不是很好

@Getter/@Setter注解

@Getter/@Setter注解的作用就是为字段添加getter/setter方法,可标注在类上,也可标注在字段上。标注在类上表示所有的非静态(no-static)字段都会生成相应的getter/setter方法,标注在字段上表示只为这个字段生成,且会覆盖标注在类上的注解。可设置访问级别,默认为public。@Setter不可以标注final字段

@[email protected]
public class SetterExample {

    @Getter(value=AccessLevel.PRIVATE)@Setter
    private String name;

    //[email protected]__({@AnnotationsHere})
    @Setter([email protected]__({@Deprecated}))
    private String age;

    //[email protected]__({@AnnotationsHere})
    @Setter([email protected]__({}))
    private String sex;

    public static void main(String[] args) {
        SetterExample se = new SetterExample();
        se.setName("zhangsan");
        se.setAge("16");
        System.out.println(se.getAge());
        System.out.println(se.getName());
    }
}

Lombok提供了onX的试验属性,分别为:onMethod, onParam, onConstructor,用于向生成的方法,构造器,参数添加注解

反编译后结果

@NonNull注解

@NonNull注解标注方法和构造器的参数,如果参数为null,则会抛出空指针异常,不需要在代码中进行null检测

public class NonNullExample {

    @Getter
    private String name;

    public NonNullExample(@NonNull String name){
        this.name = name;
    }

    public static void main(String[] args){
        String name = null;
        NonNullExample nne = new NonNullExample(name);
        System.out.println(nne.getName());
    }
}

@ToString注解

@ToString注解生成toString()方法

@ToString
public class ToStringExample {

    @ToString.Exclude
    private String name;

    @ToString.Include
    private String age;

    private String sex;

    public static void main(String[] args) {
        ToStringExample tse = new ToStringExample();
        System.out.println(tse.toString());
    }
}

属性includeFieldNames,默认为true,包含属性值

属性callSuper,默认为false,调用父类实现

属性onlyExplicitlyIncluded,默认为false,仅包含明确包含的属性

@ToString.Exclude 标注属性值不包含在toString()方法中

@ToString.Include标注属性值包含在toString()方法中

@EqualsAndHashCode

@EqualsAndHashCode注解生成equals()和hashcode()方法,注解的属性和@ToString类似

@EqualsAndHashCode
public class EqualsAndHashcodeExample {

    private String name;
    private String age;
    private String sex;

    public static void main(String[] args) {
        EqualsAndHashcodeExample ehe1 = new EqualsAndHashcodeExample();
        EqualsAndHashcodeExample ehe2 = new EqualsAndHashcodeExample();
        System.out.println(ehe1.equals(ehe2));
        System.out.println(ehe1.hashCode());
        System.out.println(ehe2.hashCode());
    }
}

@[email protected]@AllArgsConstructor

@NoArgsConstructor : 生成一个无参数的构造方法

@NoArgsConstructor(force=true, staticName="newInstance")
public class NoArgsConstructorExample {

    //包含的final字段如果没有初始化,需要加上force=true强制初始化,否则编译错误
    private final String name;

    //不会进行null检查
    @NonNull
    @Getter
    private String age;

    private String sex;

    public static void main(String[] args) {
        NoArgsConstructorExample nace1 = new NoArgsConstructorExample();
        System.out.println(nace1.getAge());
        NoArgsConstructorExample nace2 = NoArgsConstructorExample.newInstance();
        System.out.println(nace2.getAge());
    }
}

@RequiredArgsConstructor:会生成一个包含常量,和标识了NotNull的变量 的构造方法。

@RequiredArgsConstructor(staticName="newInstance")
public class RequiredArgsConstructorExample {

    private final String name;

    @NonNull
    @Getter
    private String age;

    private String sex;

    public static void main(String[] args) {
        RequiredArgsConstructorExample race1 = new RequiredArgsConstructorExample("lisi", "18");
        System.out.println(race1.getAge());
        RequiredArgsConstructorExample race2 = RequiredArgsConstructorExample.newInstance("zhangsan", "16");
        System.out.println(race2.getAge());
    }
}

@AllArgsConstructor:会生成一个包含所有变量,同时如果变量使用了NotNull annotation , 会进行是否为空的校验

@AllArgsConstructor(staticName="newInstance")
public class AllArgsConstructorExample {

    private final String name;

    @NonNull
    @Getter
    private String age;

    private String sex;
    public static void main(String[] args) {
        AllArgsConstructorExample aace1 = new AllArgsConstructorExample("zhangsan", "18", "female");
        System.out.println(aace1.getAge());
        AllArgsConstructorExample aace2 = AllArgsConstructorExample.newInstance("lisi", "16", "male");
        System.out.println(aace2.getAge());
    }
}

注意:三个注解生成的构造器都可以指定访问权限,同时也可以提供一个静态方法来供调用。三个注解的区别在于对final和@NonNull字段的处理不同

另外关于staticName属性,Lombok源码注释如下:

If set, the generated constructor will be private, and an additional static ‘constructor‘ is generated with the same argument list that wraps the real constructor.

很明显三个注解都是可以使用构造器直接创建对象的,也可以使用静态方法创建对象,不知道这段注释是什么意思???

@Data注解

等同于@ToString, @EqualsAndHashcode, @Getter, @Setter和@RequiredArgsConstructor一起使用

@Value

@Value注解为不可变类型的@Data,是@Data的一个变种。它标注的类和字段都会被声明为final

@Builder注解

@Builder注解为类生成builder api以供调用。Builder是一种解决包含数量巨大且繁杂的字段的类的一种构建方式。

假如一个类有几十个字段,那么该如何设计这个类呢?

方法一:将几十个字段都添加在构造函数中。简单粗暴,而且在构造函数中为字段初始化也能够保证对象能够正确创建。缺点就是几十个参数只会导致你在创建对象时记错参数的位置,导致不必要的麻烦。

方法二:依赖注入。Spring的核心功能之一就是依赖注入,借助这种思想,我们通过无参构造创建一个对象,然后通过setter方法设置必需的属性。这种方式可以根据需求初始化相关属性,且逻辑清晰,但也会造成代码繁琐,需要调用多次setter方法。

方法三:Builder模式。建造者模式的思想就是将一个大的类的构建分为几部分创建,从而简化创建的复杂性。

@Builder
public class BuilderExample {
    private String name;
    private String age;
    private String sex;
    public static void main(String[] args) {
        BuilderExample be = BuilderExample.builder().name("zhangsan").age("16").sex("male").build();

        System.out.println(BuilderExample.builder().name("zhangsan").age("16").sex("male"));
    }
}

@Log

@Log注解为类添加一个日志对象log,类型为java.util.logging.Logger

这个类有很多变种,详情如下:

@CommonsLog
private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(LogExample.class);

@Flogger
private static final com.google.common.flogger.FluentLogger log = com.google.common.flogger.FluentLogger.forEnclosingClass();

@JBossLog
private static final org.jboss.logging.Logger log = org.jboss.logging.Logger.getLogger(LogExample.class);

@Log
private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(LogExample.class.getName());

@Log4j
private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(LogExample.class);

@Log4j2
private static final org.apache.logging.log4j.Logger log = org.apache.logging.log4j.LogManager.getLogger(LogExample.class);

@Slf4j
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LogExample.class);

@XSlf4j
private static final org.slf4j.ext.XLogger log = org.slf4j.ext.XLoggerFactory.getXLogger(LogExample.class);

@CleanUp注解

@CleanUp注解用于关闭资源,调用资源的close()方法

public class CleanUpExample {

    @SneakyThrows({FileNotFoundException.class, Exception.class})
    public static void main(String[] args) {
        File file = new File("C:/Users/wang2/Desktop/11.jpg");
        @Cleanup
        FileInputStream is = new FileInputStream(file);
        @Cleanup
        FileOutputStream os = new FileOutputStream(new File("C:/Users/wang2/Desktop/111.jpg"));

        byte[] buffer = new byte[1024];
        int length = 0;
        while((length = is.read(buffer)) != -1){
            os.write(buffer, 0, length);
        }
    }
}

注意:抛出的异常被@SneakyThrows捕获了

@SneakyThrows注解

Sneaky的意思是偷偷摸摸地,@SneakyThrows注解的作用就是取代try...catch代码块,自动生成相应的try...catch代码块

原文地址:https://www.cnblogs.com/wxiaoqi/p/9501500.html

时间: 2024-10-06 02:37:31

优雅的Java工具库Lombok的相关文章

Bean-Query 一个把对象转换为Map的Java工具库

刚开源了一个经过完整测试的Java工具类.目前的代码已经经历了完整的测试,正在申请放到Maven central Repository上. 地址如下: https://github.com/Jimmy-Shi/bean-query 使用说明如下: Bean-query Click Here for English version. BeanQuery 是一个把对象转换为Map的Java工具库.支持选择Bean中的一些属性,对结果进行排序和按照条件查询.不仅仅可以作用于顶层对象,也可以作用于子对象

Android高手速成--第二部分 工具库

主要包括那些不错的开发库,包括依赖注入框架.图片缓存.网络相关.数据库ORM建模.Android公共库.Android 高版本向低版本兼容.多媒体相关及其他. 一.依赖注入DI 通过依赖注入减少View.服务.资源简化初始化,事件绑定等重复繁琐工作 AndroidAnnotations(Code Diet)android快速开发框架项目地址:https://github.com/excilys/androidannotations文档介绍:https://github.com/excilys/a

Android开源工具库

 一.依赖注入DI 通过依赖注入减少View.服务.资源简化初始化,事件绑定等重复繁琐工作 1. AndroidAnnotations(Code Diet) android快速开发框架 项目地址:https://github.com/excilys/androidannotations 文档介绍:https://github.com/excilys/androidannotations/wiki 官方网站:http://androidannotations.org/ 特点:(1)依赖注入:包

Android开源项目第二篇——工具库篇

本文为那些不错的Android开源项目第二篇——开发工具库篇,主要介绍常用的开发库,包括依赖注入框架.图片缓存.网络相关.数据库ORM建模.Android公共库.Android 高版本向低版本兼容.多媒体相关及其他. Android开源项目系列汇总已完成,包括: Android开源项目第一篇——个性化控件(View)篇 Android开源项目第二篇——工具库篇 Android开源项目第三篇——优秀项目篇 Android开源项目第四篇——开发及测试工具篇 Android开源项目第五篇——优秀个人和

Android 开源项目android-open-project工具库解析之(一) 依赖注入,图片缓存,网络相关,数据库orm工具包,Android公共库

一.依赖注入DI 通过依赖注入减少View.服务.资源简化初始化,事件绑定等重复繁琐工作 AndroidAnnotations(Code Diet) android快速开发框架 项目地址:https://github.com/excilys/androidannotations 文档介绍:https://github.com/excilys/androidannotations/wiki 官网网址:http://androidannotations.org/ 特点:(1) 依赖注入:包括view

GitHub上那些值得一试的JAVA开源库

作为一名程序员,你几乎每天都会使用到GitHub上的那些著名Java第三方库,比如Apache Commons,Spring,Hibernate等等.除了这些,你可能还会fork或Star一些其他的开源库,但GitHub上的库实在太多了,以至于对于个人来说,你很难有时间去发现并了解那些不断加入的新库,而它们却往往能在一些新兴领域中给你提供帮助. 我一直使用JAVA来写后端应用,平时也会关注一些国外技术大牛的博客(来自Tapki.DZone.Google Developer等技术博客),从而注意到

java 标签库(核心,xml,sql ,国际化,函数)

java标签库分分为上述几种,一般经常使用的是核心和函数,接下来会分别讲解这几种,和常见的用法. 一般标签库会和el表达式一起使用,所以在学习标签库前最后也学习下el表达式的使用. 导入后展开 可以从jar包查看相对应的标签库得tld文档,里面会描述每个标签的说明和用法 先从核心标签库开始 tld文档有几个重点,第一个就是uri,这是等下在jsp页面引入标签库时是的uri 基本一个tld文档的重点内容就这么多了,分开看其实也不是很难 1 <%@taglib uri="http://java

Java工具链(一)--项目管理工具

1.洪荒时代 大神们都在纸上写代码,打孔,代码都以段记, 好几卷厕纸才能表示一段小程序,没管理工具什么事 2.石器时代 汇编,C语言横行的时代,有文件的概念,工具极度匮乏,早慧的程序猿学会了用脚本构建自己编译打包系统,各种shell脚本满天飞 3.古代 出现了make, ant等构建工具,make是基于shell的构建工具,比较原始,模块一多各种相对路径等等满天飞(笔者在前一家公司花一星期干过一个写了18年的c项目的编译环境构建,也从头写过ndk的build系统,都烦得要死), ant感觉比ma

Android学习必备--java工具15个

Weka 1.Weka集成了数据挖掘工作的机器学习算法.这些算法可以直接应用于一个数据集上或者你可以自己编写代码来调用.Weka包括一系列的工具,如数据预处理.分类.回归.聚类.关联规则以及可视化. MassiveOnlineAnalysis 2.MassiveOnlineAnalysis(MOA)是一个面向数据流挖掘的流行开源框架,有着非常活跃的成长社区.它包括一系列的机器学习算法(分类.回归.聚类.异常检测.概念漂移检测和推荐系统)和评估工具.关联了WEKA项目,MOA也是用Java编写的,