应用办公生活信息教育商业
投稿投诉
商业财经
汽车智能
教育国际
房产环球
信息数码
热点科技
生活手机
晨报新闻
办公软件
科学动态
应用生物
体育时事

详解Lombok中的Builder及SuperBuilder

  本篇文章详细介绍了Java中lombok的Builder注解及SuperBuilder注解的解析和使用,希望对大家的学习或工作有一定的参考借鉴价值。废话不多说,直接上干货。Builder
  Lombok的Builder提供了一种非常有用的机制,无需编写样板代码即可使用构建者模式。Builder可以放在类,构造函数或方法上。基础用法
  先定义示例类Question,类声明中用Builder注解。定义Quesstion,使用Builder注解BuilderpublicclassQuestion{privateLongid;privateStringquestion;}
  用Builder注解的类,Lombok会帮我们做以下几个事情(参考下面的示例代码):定义一个名为XXXBuilder(XXX为目标类)的内部静态类,具有与静态方法(称为构建器)相同的类型参数。在构建器中:目标类的每个成员变量都有一个私有的非static非final字段。在构建器中:一个私有无参数构造函数。在构建器中:目标类的每个成员变量都有类似setter的方法:它与该成员变量具有相同的类型和相同的名称,返回构建器本身,以便可以链式调用。在构建器中:调用build()方法,传入每个字段。它返回与目标类类型相同的实例对象。在构建器中:一个合理的toString()实现。在目标类中:一个builder()静态方法,它创建构建器的一个新实例。publicclassQuestion{privateLongid;privateStringquestion;Question(Longid,Stringquestion){this。idid;this。questionquestion;}publicstaticQuestionBuilderbuilder(){returnnewQuestionBuilder();}publicstaticclassQuestionBuilder{privateLongid;privateStringquestion;QuestionBuilder(){}publicQuestionBuilderid(Longid){this。idid;returnthis;}publicQuestionBuilderquestion(Stringquestion){this。questionquestion;returnthis;}publicQuestionbuild(){returnnewQuestion(this。id,this。question);}publicStringtoString(){returnQuestion。QuestionBuilder(idthis。id,questionthis。question);}}组合用法
  Builder中使用Singular注释集合。定义Answer,使用Builder注解BuilderpublicclassAnswer{privateLongid;privateStringanswer;}定义Quesstion,使用Builder注解BuilderpublicclassQuestion{privateLongid;privateStringquestion;SingularprivateListanswers;Singular(answer)privateListanswerList;}
  在使用Singular注释注释一个集合字段(使用Builder注释类),lombok会将该构建器节点视为一个集合,并生成两个adder方法,而不是setter方法。一个往集合添加单个元素;一个将另一个集合的所有元素添加到集合中;
  除此之外,还生成了clear方法,用于清空集合。publicclassQuestion{privateLongid;privateStringquestion;Listanswers;Question(Longid,Stringquestion,Listanswers){this。idid;this。questionquestion;this。answersanswers;}publicstaticQuestionBuilderbuilder(){returnnewQuestionBuilder();}publicstaticclassQuestionBuilder{privateLongid;privateStringquestion;privateArrayListanswers;QuestionBuilder(){}publicQuestionBuilderid(Longid){this。idid;returnthis;}publicQuestionBuilderquestion(Stringquestion){this。questionquestion;returnthis;}publicQuestionBuilderanswer(Answeranswer){if(this。answersnull){this。answersnewArrayList();}this。answers。add(answer);returnthis;}publicQuestionBuilderanswers(Collectionlt;?extendsAnsweranswers){if(answersnull){thrownewNullPointerException(answerscannotbenull);}else{if(this。answersnull){this。answersnewArrayList();}this。answers。addAll(answers);returnthis;}}publicQuestionBuilderclearAnswers(){if(this。answers!null){this。answers。clear();}returnthis;}publicQuestionbuild(){Listanswers;switch(this。answersnull?0:this。answers。size()){case0:answersCollections。emptyList();break;case1:answersCollections。singletonList(this。answers。get(0));break;default:answersCollections。unmodifiableList(newArrayList(this。answers));}returnnewQuestion(this。id,this。question,answers);}publicStringtoString(){returnQuestion。QuestionBuilder(idthis。id,questionthis。question,answersthis。answers);}}}
  从上面代码块,可以看到在集合字段增加了Singular注解后,构建器的build()方法会更复杂一些,主要是为了保证以下两点:在调用build()时,生成的集合将是不可变的。在调用build()之后调用其中一个adder方法或clear方法不会修改任何已经生成的对象。如果对集合修改之后,再调用build(),则会创建一个基于上一个对象创建的对象实体。生成的集合将被压缩到最小的可行格式,同时保持高效。
  如果您的标识符是用普通英语编写的,lombok会假定任何带有Singular的集合的名称是英语复数,并将尝试自动将该名称单数化。如果可能,addone方法将使用此名称。例如,如果这里我们定义的集合为answers,那么addone方法将自动称为answer(Answeranswer)。您还可以在Singular注解中显式指定标识符的单数形式,如上面代码块中被注释的部分:Singular(answer)privateListanswerList;
  如果lombok无法将您的标识符单数化,或者它有歧义,lombok将生成错误并强制您明确指定单数名称。
  Builder。Default的使用
  如果在构建会话期间从未设置某个字段参数,则它始终为0nullfalse。如果您将Builder放在类上(而不是方法或构造函数),您可以直接在字段上指定默认值,并使用Builder。Default注释该字段:BuilderpublicclassAnswer{Builder。DefaultprivatefinalStringidUUID。randomUUID()。toString();privateStringanswer;}
  Builder(toBuildertrue)
  如果我们想要创建对象的副本或近似副本,我们可以将属性toBuildertrue添加到Builder注释中:
  Lombok会在目标类中新增一个toBuilder()方法。当调用toBuilder()方法时,它会返回一个新的构建器,该构建器使用调用它的实例的属性进行初始化:publicclassAnswer{privatefinalStringid;privateStringanswer;privatestaticStringdefaultid(){returnUUID。randomUUID()。toString();}Answer(Stringid,Stringanswer){this。idid;this。answeranswer;}publicstaticAnswerBuilderbuilder(){returnnewAnswerBuilder();}publicAnswerBuildertoBuilder(){return(newAnswerBuilder())。id(this。id)。answer(this。answer);}publicstaticclassAnswerBuilder{privatebooleanidset;privateStringidvalue;privateStringanswer;AnswerBuilder(){}publicAnswerBuilderid(Stringid){this。idvalueid;this。idsettrue;returnthis;}publicAnswerBuilderanswer(Stringanswer){this。answeranswer;returnthis;}publicAnswerbuild(){Stringidvaluethis。idvalue;if(!this。idset){idvalueAnswer。defaultid();}returnnewAnswer(idvalue,this。answer);}publicStringtoString(){returnAnswer。AnswerBuilder(idvaluethis。idvalue,answerthis。answer);}}}SuperBuilder
  Builder并不支持对父类成员属性的构造,为解决这个问题,SuperBuilder应运而生,算是Builder的升级版。SuperBuilder在lombokv1。18。2中作为实验性功能引入。
  定义示例类Event和其子类QuestionEvent。SuperBuilderpublicclassEvent{Stringmessage;}SuperBuilderpublicclassQuestionEventextendsEvent{}
  用SuperBuilder注解的类,Lombok会帮我们做以下几个事情(参考下面的示例代码):SuperBuilder在以builder实例作为参数的类上生成一个protect类型的构造函数。此构造函数将新实例的字段设置为builder中的值。为了确保类型安全,SuperBuilder为每个注解类生成两个内部构建器类,一个抽象类和一个具体类,名为XXXBuilder和XXXBuilderImpl(其中XXX是注解类的名称)。publicclassEvent{Stringmessage;protectedEvent(EventBuilderlt;?,?b){this。messageb。message;}publicstaticEventBuilderlt;?,?builder(){returnnewEventBuilderImpl();}privatestaticfinalclassEventBuilderImplextendsEventBuilderEvent,EventBuilderImpl{privateEventBuilderImpl(){}protectedEventBuilderImplself(){returnthis;}publicEventbuild(){returnnewEvent(this);}}publicabstractstaticclassEventBuilderCextendsEvent,BextendsEventBuilderC,B{privateStringmessage;publicEventBuilder(){}protectedabstractBself();publicabstractCbuild();publicBmessage(Stringmessage){this。messagemessage;returnthis。self();}publicStringtoString(){returnEvent。EventBuilder(messagethis。message);}}}publicclassQuestionEventextendsEvent{protectedQuestionEvent(QuestionEventBuilderlt;?,?b){super(b);}publicstaticQuestionEventBuilderlt;?,?builder(){returnnewQuestionEventBuilderImpl();}privatestaticfinalclassQuestionEventBuilderImplextendsQuestionEventBuilderQuestionEvent,QuestionEventBuilderImpl{privateQuestionEventBuilderImpl(){}protectedQuestionEventBuilderImplself(){returnthis;}publicQuestionEventbuild(){returnnewQuestionEvent(this);}}publicabstractstaticclassQuestionEventBuilderCextendsQuestionEvent,BextendsQuestionEventBuilderC,BextendsEvent。EventBuilderC,B{publicQuestionEventBuilder(){}protectedabstractBself();publicabstractCbuild();publicStringtoString(){returnQuestionEvent。QuestionEventBuilder(supersuper。toString());}}}为什么Builder不能处理父类的成员变量,而SuperBuilder可以?
  原因在于,在Java的抽象语法树设计上,每个类只包含了显式声明的变量而不包括父类的成员变量。Lombok针对Builder注解的内部实现findAllFields方法是从当前类的抽象语法树出发去找所有的成员变量,所以就只能找到当前类的成员变量,而访问不到父类的成员变量。
  SuperBuilder注解的内部实现,在查找所有成员变量之前,先拿到了继承的父类的抽象语法树。JCClassDecltd(JCClassDecl)parent。get();获取继承的父类的抽象语法树JCTreeextendsClauseJavac。getExtendsClause(td);JCExpressionsuperclassBuilderClassnull;if(extendsClauseinstanceofJCTypeApply){Rememberthetypearguments,becauseweneedthemfortheextendsclauseofourabstractbuilderclass。superclassTypeParams((JCTypeApply)extendsClause)。getTypeArguments();Aclassnamewithagenericstype,e。g。,Superclass。extendsClause((JCTypeApply)extendsClause)。getType();}if(extendsClauseinstanceofJCFieldAccess){NamesuperclassName((JCFieldAccess)extendsClause)。getIdentifier();StringsuperclassBuilderClassNamesuperclassName。toString()Builder;superclassBuilderClassparent。getTreeMaker()。Select((JCFieldAccess)extendsClause,parent。toName(superclassBuilderClassName));}elseif(extendsClause!null){StringsuperclassBuilderClassNameextendsClause。toString()Builder;superclassBuilderClasschainDots(parent,extendsClause。toString(),superclassBuilderClassName);}注意点SuperBuilder与Builder不兼容,不能一起使用。被SuperBuilder注解的类,其父类也必须使用SuperBuilder注解。

魔兽争霸3常规对局中,这些英雄往那一站,都能让人头皮发麻对战模式中战斗力强大的英雄并不算少,之前的文章中也为大家介绍了很多。今天,我们就一起来看看,那些在常规对局中,只需要往那一站,就能让对手望而生畏的英雄。这些英雄中,有些输出能力……天玑9200骁龙8Gen2陆续发布,为什么A16表示毫无压力头条创作挑战赛众所周知,天玑9200、骁龙8Gen2处理器已经是未来2023年一大批新旗舰机的内定平台。所以受到了广大安卓用户的一致关注,但对于苹果用户来说,他们的内心却……共享宜遥便利绿色出行踏青州晨曦日露非常记,春泥蹄过涂巷芳。出行的方式是近几年人们讨论的焦点话题,在这个能源化的时代,绿色出行一直常常出现在人们的视野之中。究竟什么样的出行方式才够健康,够时尚?人们推陈出……急救或抱佛脚?曝郑智向老板申请赢球奖,广州队教练决定亲自下场1比5!广州队的历史惨败纪录又多了一战,也不得不让中超八冠王又整一出。根据一位体育博主爆料称,郑智认为还有两个补救措施可以使用:向许老板申请赢球奖,主教练亲自下场。对于这样的传……为什么有的人很有本事,但却没有草根挣钱多中醫疑難病證指南作者鄔學芳2022。11。16日本事就是能力,能力应该涵盖心能与体能。如果双管齐下,从政与艺业争钱都是如鱼得水,岂能会争不到钱呢?如果争不到钱……鼓励对抗就能无视生命?CBA联赛球员被连续踩踏,裁判也不吹停本赛季(即20222023赛季)的CBA全国男子篮球职业联赛出现了全新的执法风格,就是鼓励对抗,保持比赛流畅度。但鼓励对抗就能无视生命?CBA联赛球员被连续踩踏,裁判也不吹停!……浮生茶语秋天的韵味秋,来得不声不响,好像季节一到,只是睡了一觉醒来,到处就都充满着秋的味道。风,不再灼热难耐;雨,总在人们熟睡的时候悄悄来过,就像这秋来的时候一样,蹑手蹑脚不动声色把树上的……长沙锚定长远加快建设科技创新高地长沙晚报全媒体记者徐运源通讯员夏斯翔打造具有核心竞争力的科技创新高地,是习近平总书记考察湖南时的殷殷嘱托。在长沙非凡十年新闻发布会上,一系列具体举措成就的一系列亮眼数据,……别忽视甲减!这6种病都和它有关系很多人对甲减这个病不是很了解,以为甲减和亚健康一样,就是疲劳等轻微的症状,不会有实质性的伤害,实则不然,甲减和很多疾病都有关系,比如下面这几种:高血脂甲减时缺少甲状……酒局上最不动声色的人,往往最聪明,可别小瞧他了,得罪不起呀常言道,沉默是金,言多必失,无论在什么样的场合都应该懂得,外表可以其貌不扬,但内心要沉着冷静。常常会看到讲话滔滔不绝的人,如果不是工作的性质需要,没必要讲太多的话,真的是……吃了一次清炒蒲瓜片,太惊艳了吃了一次清炒蒲瓜片,太惊艳了!就放了点虾米,放了点儿蒜蓉,看起来超级清淡,没想到吃起来这么好吃。所有人的筷子一致伸向这一盘,三下五除二就光了。连吃两顿,到了下一个店……中药里面的痰淤克星,祛痰生新,活血化淤体内有痰还有淤,痰瘀互结怎么办?《黄帝内经》里记载:癌瘤者,非阴阳正气所结,乃五脏瘀血浊气痰滞而成。所以体内有痰还有淤是一个很危险的信号,可能癌症、肿瘤正悄悄靠近,清除体……
张本智和吃败仗,妹妹加冕双冠王,张本美和再轰110闪耀世青赛北京时间12月8日,乒乓球世青赛结束第六比赛日争夺。国乒拿下U19女双冠军,蒯曼和吴洋晨晋级U19女单四强,向鹏和曾蓓勋晋级U19男单四强。日本方面,张本美和携手外协会选手,拿……更年期的女人三甜伤脸,易长斑,建议管住嘴,做个精致女人对于女性来说,随着年龄的增长,逐渐进入更年期,这也是多数女性所抗拒的一件事,因为进入更年期之后,也将面临着绝经。而且身体内部的激素失衡,影响到皮肤的状态,加速衰老到来,也……蛮族之王随心而动,随刃而行。身高187CM、体重80KG,百米10秒6,起跳高度2米88。他是足球场上的人形加特林,不知疲倦的射门机器,史上最勤奋、富有进取心的进球永动机。……装好自己的情绪按钮(随笔)情绪常常我行我素,不受控制,不听招呼,常常在不该发脾气的时间、地点发作,为自己无端增添许多麻烦。怎么才能为自己的情绪装上按钮,让其受理性控制,使其在不该发脾气的时候处于关闭模式……惊险!3岁姐姐给10个月大妹妹喂了颗花生,差点要了妹妹的命现代快报讯(通讯员林秋红记者王晓宇)疫情期间,大伙居家生活,花生、瓜子等零食成为不少人打发时间最好的东西。近日,因为家长的一个不小心,连云港王女士(化名)家10个月大的女儿差点……雨后的风景,更美了雨,是最常见的,最寻常的,它是天空的眼泪,是天空释放心情的表现。喜欢雨,喜欢清晨雨的朦胧,喜欢雨后形成小水洼中的倒影。一颗石化的心,化作一滴泪,倒影在三生壶里,让我喝下这世间最……50分53分60分!欧文不藏着掖着,KD也彻底摊牌,哈登后悔NBA常规赛继续,东部迎来一场强弱对话,魔术坐镇主场迎战篮网。由于是客场作战,这是欧文在剩余常规赛中为数不多可以出战的比赛,加上篮网队近来状态不俗,在杜兰特的带领下拿下了……POE必将成为重中之重!160万吨在建产能!聚烯烃弹性体(POE)是高端聚烯烃的一种。POE是以乙烯为主要聚合单元,以烯烃(以48个碳的烯烃为主,如丁烯、己烯、辛烯)为共聚单体进行聚合得到的共聚物。与普通聚烯烃相比,其分……六年的时间长跑,战舰世界始终不曾停歇从2015年上线公测至今,《战舰世界》已然陪伴我们走过了六年的时间。从最初的公测到如今的全球同步开启,《战舰世界》陪伴许多人度过了青春。尽管中间存在着些许的波折,但《战舰世界》……1969年美国有意向中国透露苏联要用核武器,毛主席的回答真高英国首相温斯顿丘吉尔曾说过:没有永远的朋友,只有永远的利益。这句话听上去或许有些刺耳,但是在人类几千年的历史上一次次证明,它是颠扑不破的真理。中国与苏联之间,曾经一度十分……男子1199元买长江存储2TBSSD吐槽是翻新手指划痕网友看本月初,长江存储TiPlus71002TBSSD推出,售价1199元,这引起了不少网友的关注。TiPlus7100升级晶栈Xtacking3。0架构闪存,高达2400MT……速滑运动员凯丽,跟三位世界冠军驰骋冰场,自嘲是混子上午,老戏骨张凯丽在社交平台发布《冬梦之约》节目预告,北京卫视今晚9点,与三位世界冠军叶乔波、王濛、周洋一起,赴双奥之约,燃冬奥之梦。微博一发布,可引起了不少网友关注,很……
友情链接:快好找快生活快百科快传网中准网文好找聚热点快软网