lombok 自动使用_Lombok,自动值和不可变项

lombok 自动使用

我喜欢布兰登(Brandon )在博客文章中比较Project Lombok , AutoValue和Immutables的建议 ,而这篇文章试图做到这一点。 我已经简要概述了Project Lombok , AutoValue和Immutables ,但是这篇文章有所不同,因为它突出了它们之间的异同。

Lombok, AutoValue和Immutables有很多相同之处,我尝试用以下单个描述性句子总结这些相似之处:Lombok,AutoValue和Immutables使用注释处理为值对象类所使用的常见操作生成样板代码。 本文的其余部分将更详细地探讨这些相似之处,并对比这三种方法。

代码生成

Lombok,AutoValue和Immutables均旨在从简洁的代码表示形式生成详细的样板代码,这些代码表示形式专注于高级业务逻辑,而将实现的低级细节留给代码生成。 常见的对象方法,例如toString() , equals(Object)和hashCode()很重要,但需要正确编写。 容易犯这些错误,即使最初正确地编写了这些错误(包括通过IDE生成),但在对类产生影响的其他更改时也可以忽略它们。

价值对象

Lombok , AutoValue和Immutables均支持生成“ 值对象” 。 尽管AutoValue严格执行值对象的生成,但如果指定了@Modifiable ,则Immutables允许生成的对象是可修改的,并且Lombok在其生成的类中使用@Set和@Data等批注支持多级修改。

超越价值对象

AutoValue专注于值对象的生成,并基于模板类中的抽象方法,支持字段,构造函数/生成器,具体访问器方法的生成以及常见方法equals(Object)hashCode()toString()的实现。

Immutables提供的功能类似于AutoValue提供的功能,并添加了使用@ Value.Modifiable生成可修改类的功能 。 不可变对象还提供其他功能 ,包括:

  • 单例实例
  • 预先计算的哈希码
  • 实例实习
  • 可自定义的equals(Object),hashCode()和toString()实现,包括从中排除字段
  • 基本和高级序列化

Lombok提供了类似于具有@Value批注的AutoValue的值类生成功能,并提供了使用@Data批注生成可修改类的功能。 Lombok还提供其他功能 ,包括:

  • 资源清理
  • 记录器字段生成
  • 同步对象锁
  • 潜入检查的异常

基于注释处理

Lombok , AutoValue和Immutables都通过注释处理从更简洁的模板代码生成了更多冗长的样板代码。 每个都包含一个在其JAR文件的META-INF/services区域javax.annotation.processing.Processor定义的javax.annotation.processing.Processor ,作为javac编译器一部分的标准注释处理器发现过程的一部分 。

并非所有注释处理都相同

尽管Lombok,AutoValue和Immutables都通过javac进行注释处理 ,但是Lombok如何使用注释处理的细节与AutoValue和Immutables的处理方法不同。 AutoValue和Immutables在更常规的意义上使用注释处理,并从源生成源。 由AutoValue和Immutables生成的类源代码的名称与模板类不同,实际上是扩展了模板类。 AutoValue和Immutables都读取模板类,并在Java源代码中生成一个具有自己名称的全新类,该类具有所有生成的方法和字段。 这避免了与模板类的任何名称冲突,并且使模板类源代码和生成的类源代码在同一IDE项目中的混合相当容易,因为它们实际上是不同的类。

通过注释处理生成AutoValue

20160622-autoValueJavacAnnotationsProcessing.copy

通过注释处理生成不可变对象

20160622-immutablesJavacAnnotations处理

Lombok通过与AutoValue和Immutables不同的注释处理来实现生成。 Lombok生成具有与“模板”源代码相同的类名的已编译.class文件,并将生成的方法添加到此已编译版本中。 开发人员仅在查看.java文件时会看到简洁的模板代码,而在查看.class文件时会看到源代码中不存在的方法的编译后的.class文件。 Lombok生成的不是另一个源文件,而是原始源的增强编译版本。 有一个delombok选项可以与Lombok一起使用,以查看增强的.class文件背后生成的源代码是什么样子,但该项目的真正目的是从简洁的模板源直接转换为增强的编译类,而无需使用或使用中间增强功能。源文件。 delombok选项可用于查看生成的源的外观,或者更重要的是,可以在将其与工具混淆以使源(简洁的模板.java文件)和生成的类(生成的类)不一致的情况下使用.class同名的.class文件)。

Lombok通过注释处理生成

20160622-lombokJavacAnnotations处理

Lombok的注释处理方法不像AutoValue和Immutables所采用的方法那样传统,并且包括Lombok的创建者在内的一些人将这种方法称为“ hack” 。 Neildo的帖子Lombok – Trick Explained中很好地解释了Lombok的“技巧”或“ hack”,并引用了内容丰富的OpenJDK编译概述 。

围绕Lombok的方法引起争议的主要原因密切相关,并且是它使用了非标准的API,因此,很难与IDE和执行自己的编译的其他工具(例如javadoc )很好地集成。 由于AutoValue和Immutables自然会使用新的类名生成源代码,因此任何传统工具和IDE都可以将生成的源代码与模板源代码一起使用,而不会出现任何重大问题。

异同摘要

特性 Lombok计划 自动值 不可变的 注释
涵盖版本 1.16.8 ( 2016年 ) 1.2 ( 2016 ) 2.2.8 (2016年) 此帖子使用的版本
起源年份 2009年 2014年 2014年
执照 麻省理工 ( 也 ) 阿帕奇2 阿帕奇2 全部开源
最低Java 1.6 1.6 1.7 支持的最旧的Java版本
依存关系 ASM ( 用于Eclipse集成 ) ASM (可选) 运行时依赖项 : Guava 编译时依赖(包括)的库
javax.annotation.processing.Processor lombok.launch.AnnotationProcessorHider $ AnnotationProcessor com.google.auto.value.processor.AutoAnnotationProcessor
com.google.auto.value.processor.AutoValueBuilderProcessor
com.google.auto.value.processor.AutoValueProcessor
org.immutables.processor.ProxyProcessor 标准注释处理器规范位置
生成的源与模板源的关系 增强的生成类替换模板源 生成的源扩展了模板源 Lombok仅显示带有“ delombok”选项的生成源
访问生成的源 指定delombok选项 默认 默认 查看/控制生成的源代码
生成方法 equals(Object) , hashCode() , toString() , 构造 /生成器 , 访问器 , 设置器 equals(Object),hashCode(),toString(),构造/生成器,访问器 equals(Object) , hashCode() , toString() , 构造 /生成器 ,访问器, 设置器
不变程度 允许使用字段级@Set进行完全可变,但在需要不可变性时提供@Value 加强严格的不变性 “ 偏重于不变性 ”,但提供了类级别的@ Value.Modifiable AutoValue的意见最多,Lombok的意见最少
奖励功能 资源清理
不可变或可变
偷偷地抛出检查异常 对象同步锁 记录注释 更多 …
忠实于价值客体的概念
记录的最佳做法
样式定制
序列化 (包括JSON )
预先计算的哈希码 更多…

选择时的注意事项

Lombok,AutoValue和Immutables是类似的工具包,它们提供类似的好处,并且这三种方法中的任何一种都可以被广泛的应用程序成功使用。 但是,在选择使用哪个工具箱时,可以考虑它们之间的差异。

  • Lombok生成具有与模板相同的包和类名称的类,而AutoValue和Immutables生成扩展模板类并具有自己的类名的类(但包相同)。
    • 希望已编译的.class文件具有与模板类完全相同的包和名称的开发人员将首选Lombok。
  • AutoValue是这三个工具包中最自以为是的,而Lombok则是最不自以为是的。
    • 希望严格执行“值对象”特征的开发人员可能更喜欢AutoValue。
  • AutoValue和Immutables使用标准注释处理,而Lombok使用非标准注释处理方法。
    • 希望避免非标准依赖关系的开发人员将倾向于使用AutoValue或Immutables。
  • 这三个工具箱都支持某种程度的自定义,并且希望自定义所生成代码的开发人员可能希望选择允许他们以所需方式自定义所生成代码的工具箱。
    • Lombok提供了一种配置系统 ,该系统允许将生成的代码的多个方面调整为所需的约定。
  • JDK 1.6支持AutoValue和Lombok,但Immutables需要JDK 1.7。

结论

Lombok,AutoValue和Immutables有很多共同点,并且全部三个都可以用来从简单的模板文件生成值类。 但是,它们各自提供不同的优势和功能,这可能会导致它们中的任何一个相对于其他开发者更具吸引力,这取决于开发者的个人情况。

翻译自: https://www.javacodegeeks.com/2016/06/lombok-autovalue-immutables.html

lombok 自动使用

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/335885.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

邮箱批量登录接验证码_记一次莫名的需求(临时邮箱|企业邮箱)

目录:前言行情伪需求过程1.前戏2.买域名3.网易企业邮箱4.模糊的需求5.晚饭后6.临时邮箱16.临时邮箱27.域名版临时邮箱8.遇见问题8.1.DNSPOD8.2.换种思路拓展1.思路2.后续2.1.简单2.2.自建临时邮箱后话记一次需求不明的亏看完这篇文章你会学到: 免费企业邮…

java 补充日期_Java 9对可选的补充

java 补充日期哇&#xff0c;人们真的对Java 9对Stream API的添加感兴趣。 想要更多&#xff1f; 让我们看一下…… 可选的 可选::流 无需解释&#xff1a; Stream<T> stream();想到的第一个词是&#xff1a; 终于 &#xff01; 最后&#xff0c;我们可以轻松地从可选…

【Python科学计算系列】行列式

1.二元线性方程组求解 import numpy as np a np.array([[3, -2], [2, 1]]) b np.array([12, 1]) d np.linalg.solve(a, b) print(d) 2.三阶行列式求值 import numpy as np a np.array([[1, 2, -4], [-2, 2, 1], [-3, 4, -2]]) d np.linalg.det(a) print(d) 3.行列式的余…

【Python科学计算系列】矩阵

1.矩阵的幂计算&#xff08;设计思想&#xff1a;递归&#xff09; #!/usr/bin/env python # -*- coding: utf-8 -*- import numpy as np def matrixPow(Matrix,n):if(type(Matrix)list):Matrixnp.array(Matrix)if(n1):return Matrixelse:return np.matmul(Matrix,matrixPow(…

swarm 本地管理远程_带有WildFly Swarm的远程JMS

swarm 本地管理远程我再次在博客中谈论WildFly群&#xff1f; 简短的版本是&#xff1a;我需要对远程JMS访问进行测试&#xff0c;并且拒绝设置复杂的功能&#xff08;如完整的应用程序服务器&#xff09;。 这个想法是要有一个简单的WildFly Swarm应用程序&#xff0c;该应用程…

java解码_Java数组已排序解码

java解码排序是我们在计算机科学中学习的第一个算法。 排序是一个非常有趣的领域&#xff0c;它有大约20多种算法&#xff0c;而且总是很难确定哪种算法最好。 排序算法的效率是根据占用的时间和所需的空间来衡量的。 一些时间气泡排序是最好的&#xff0c;因为它没有空间需求&…

【数论系列】反函数

一、判断反函数是否存在&#xff1a; 由反函数存在定理&#xff1a;严格单调函数必定有严格单调的反函数&#xff0c;并且二者单调性相同&#xff1a; 1、先判读这个函数是否为单调函数&#xff0c;若非单调函数&#xff0c;则其反函数不存在。 设yf(x)的定义域为D&#xff…

java附加属性_Java 9附加流

java附加属性Java 9即将发布&#xff01; 它不仅仅是Jigsaw项目 。 &#xff08;我也很惊讶。&#xff09;它给平台带来了很多小的变化&#xff0c;我想一一看一下。 我将标记所有这些帖子&#xff0c;您可以在这里找到它们。 让我们从…开始 流 Streams学习了两个新技巧。 第…

envi最大似然分类_闲谈最大后验概率估计(MAP estimate)amp;极大似然估计(MLE)和机器学习中的误差分类...

上一篇文章中提到了一个有趣的实验&#xff0c;简单来说就是1-100中有若干个数字是“正确的”&#xff0c;只告诉其中一部分“正确的”数字&#xff0c;去猜全部“正确的”数字。为了严谨的去研究这个问题&#xff0c;我们需要将一些概念进行抽象。首先&#xff0c;把提前告知的…

html 完全复制div中的内容_LOL手游现在远非完全体,未来还有哪些端游内容会加入手游中?...

LOL手游上线已经有一段时间了&#xff0c;虽然绝大多数情况下LOL端游的内容被继承到了手游当中&#xff0c;但是仍然有一部分端游的内容尚未出现在手游之内。今天小编就带领大家来盘点一下&#xff0c;那些未来可能出现在手游当中的端游内容。排位赛ban选英雄机制Moba游戏排位赛…

光盘 机密_使用保险柜管理机密

光盘 机密您如何存储秘密&#xff1f; 密码&#xff0c;API密钥&#xff0c;安全令牌和机密数据属于秘密类别。 那是不应该存在的数据。 在容易猜测的位置&#xff0c;不得以纯文本格式提供。 实际上&#xff0c;不得在任何位置以明文形式存储它。 可以使用Spring Cloud Confi…

junit5 动态测试_JUnit 5 –动态测试

junit5 动态测试在定义测试时&#xff0c;JUnit 4有一个很大的弱点&#xff1a;它必须在编译时发生。 现在&#xff0c;JUnit 5将解决此问题&#xff01; Milestone 1 刚刚发布 &#xff0c;它带有全新的动态测试&#xff0c;可以在运行时创建测试。 总览 本系列中有关JUnit 5…

C++ 11 深度学习(十)原始字面量

你是否曾经为了各种json格式无法写入string中而烦恼&#xff0c;为了各种转义而烦恼。如下图 c11为我们带来了全新的解决方法 其新特性为使用. R"(xxxxxxxxxxxx)" ,此种形式可以使得以原有形式进行表现出来

交流伺服系统设计指南_交流设计

交流伺服系统设计指南软件设计至关重要。 它是应用程序的基础。 就像蓝图一样&#xff0c;它为所有背景的聚会提供了一个通用平台。 它有助于理解&#xff0c;协作和发展。 设计不应仅视为开发的要素。 它不应该仅仅存在于开发人员的脑海中&#xff0c;否则团队将发现它几乎无…

maven 父maven_Maven神秘化

maven 父maven由于我的Android开发的背景下&#xff0c;我比较习惯到Gradle &#xff0c;而不是Maven的 。 尽管我知道Gradle基于Maven&#xff0c;但我从未调查过幕后发生的事情。 在过去的一周中&#xff0c;我一直在尝试了解细节并找出Maven的不同组成部分。 什么是Maven M…

【WebRTC---序篇】(一)为什么要使用WebRTC

1.1.1自研直播客户端架构 一个最简单的直播客户端至少应该包括音视频采集模块,音视频编码模块,网络传输模块,音视频解码模块和音视频渲染模块五大部分。如下图所示 1.1.2拆分音视频模块 在实际开发中,音频和视频处理完全是独立的。如下图所示,经过细分后,音频采集与视频…

DFS深搜与BFS广搜专题

一般搜索算法的流程框架 DFS和BFS与一般搜索流程的关系 如果一般搜索算法流程4使用的是stack栈结构(先进后出&#xff0c;后进先出)那么就会越搜越深。即&#xff0c;DFS&#xff0c;DFS只保存当前一条路径&#xff0c;其目的是枚举出所有可能性。反之&#xff0c;如果流程4使…

cloud foundry_使用“另类” Cloud Foundry Gradle插件无需停机

cloud foundry我一直在尝试编写用于将应用程序部署到Cloud Foundry的gradle插件 &#xff0c;并在上一篇文章中写了有关此插件的文章 。 现在&#xff0c;我通过使用两种方法支持将无停机时间部署到Cloud Foundry中来增强此插件&#xff1a; 自动驾驶风格部署和更常用的蓝绿色风…

懒惰学习_懒惰评估

懒惰学习最近&#xff0c;我正在编写log4j附加程序&#xff0c;并希望在自定义附加程序创建过程中使用logger记录一些诊断详细信息&#xff0c;但是log4j初始化仅在创建附加程序实例后才完成&#xff0c;因此在此阶段记录的消息将被忽略。 我感到需要在自定义附加程序中进行延…

leetcode(动态规划专题)

线性DP 53. 最大子数组和 思路 code int maxSubArray(vector<int>& nums) {//res:最后所有状态的最终Max结果//lat:当前f[i]状态的Maxint res INT_MIN, last 0;for (int i 0; i < nums.size(); i){//当前f[i]状态最大值(使用下面的状态转移方程得出)//f[i] …