Project Lombok: Clean, Concise Java Code - Oracle
文章推薦指數: 80 %
The Lombok library was created to make Java an easier language in which to code. It takes some of the most common boilerplate headaches out of the developer's ...
ClicktoviewourAccessibilityPolicy
Skiptocontent
home
nav
Oracle
Close
Search
Search
Products
Industries
Resources
Support
Events
Developer
Partners
ViewAccountsSignIn
Back
OracleAccount
CloudAccount
SignintoCloud
SignUpforFreeCloudTier
Sign-In
CreateanAccount
Help
SignOut
ContactSales
Noresultsfound
Yoursearchdidnotmatchanyresults.
Wesuggestyoutrythefollowingtohelpfindwhatyou’relookingfor:
Checkthespellingofyourkeywordsearch.
Usesynonymsforthekeywordyoutyped,forexample,try“application”insteadof“software.”
Tryoneofthepopularsearchesshownbelow.
Startanewsearch.
TrendingQuestions
Close
AboutOracle
JavaDeveloper|Libraries
ProjectLombok:Clean,ConciseJavaCode
AddLomboktoyourprojectandgetridofmostofyourboilerplatecode.
ByJoshJuneau
ImaginethatyouarecodingaJavaapplicationandcreatingaplainoldJavaobject(POJO),aJavaclasswithseveralprivatefieldsthatwillrequiregetterandsettermethodstoprovideaccess.Howmanylinesofcodewillbeneededtogenerate
gettersandsettersforeachofthefields?Moreover,addingaconstructorandatoString()methodwillcauseevenmorelinesofcodeandclutter.Thatisalotofboilerplatecode.HowaboutwhenyouareutilizingJavaobjectsthatneedtobeclosedafteruse,soyouneedtocodeafinallyblockorusetry-with-resourcestoensurethattheobjectclosingoccurs?Addingfinallyblockboilerplatetocloseobjectscanaddasignificantamountofcluttertoyourcode.
ProjectLombokisamaturelibrarythatreducesboilerplatecode.ThecasesmentionedabovecoverjustafewofthosewhereProjectLombokcanbeagreatbenefit.Thelibraryreplacesboilerplatecodewitheasy-to-useannotations.Inthisarticle,IexamineseveralusefulfeaturesthatProjectLombokprovides—makingcodeeasiertoreadandlesserror-proneandmakingdevelopersmoreproductive.Bestofall,thelibraryworkswellwithpopularIDEsandprovidesautilityto“delombok”yourcodebyreverting—thatis,addingbackalltheboilerplatethatwasremovedwhentheannotationswereadded.
CheckforNulls
Let’sstartwithoneofthemostbasicutilitiesthatLombokhastooffer.The@NonNullannotation,whichshouldnotbeconfusedwiththeBeanValidationannotation,canbeusedtogenerateanullcheckonasetterfield.ThecheckthrowsaNullPointerExceptioniftheannotatedclassfieldcontainsanullvalue.Simplyapplyittoafieldtoenforcetherule:
@NonNull@Setter
privateStringemployeeId;
Thiscodegeneratesthefollowingcode:
publicidsetEmployeeId(@NonNullfinalStringemployeeId)
{
if(employeeId==null)throw
newjava.lang.NullPointerException("employeeId");
this.employeeId=employeeId;
[email protected],awarningisissuedandnonullcheckisgenerated.
ConciseDataObjects
WritingaPOJOcanbelaborious,especiallyiftherearemanyfields.IfyouaredevelopingaPOJO,youshouldalwaysprovideprivateaccessdirectlytotheclassfields,whilecreatingaccessormethods—gettersandsetters—toreadfromandwritetothosefields.Althoughdevelopingaccessormethodsiseasy,theygenerallyarejustboilerplatecode.Lombokcantakecareofgeneratingthesemethodsifafieldisannotatedwith@[email protected],thefollowingtwocodelistingsprovidetheexactsamefunctionality.
WithoutProjectLombok:
privateStringcolumnName;
publicStringgetColumnName(){
returnthis.columnName;
}
publicvoidsetColumnName(StringcolumnName){
this.columnName=columnName;
}
UsingProjectLombok:
@Getter@SetterprivateStringcolumnName;
Asyoucansee,Lomboknotonlymakesthecodemoreconcise,butitalsomakesthecodeeasiertoreadandlesserror-prone.Theseannotationsalsoacceptanoptionalparametertodesignatetheaccesslevelifneeded.Moregoodnews:@Getterand@Setterrespectthepropernamingconventions,sogeneratedcodeforaBooleanfieldresultsinaccessormethodsbeginningwithisratherthanget.Iftheyareappliedattheclasslevel,gettersandsettersaregeneratedforeachnonstaticfieldwithintheclass.
Lombokcantakecareoftheloggerdeclarationifyouplacethe@Logannotation(oranannotationpertainingtoyourchoiceofloggingAPI)onanyclassthatrequiresloggingcapability.
Inmanycases,dataobjectsalsoshouldcontaintheequals(),hashCode(),andtoString()methods.Thisboilerplatecanbetakencareofbyannotatingaclasswiththe@EqualsAndHashCodeand@ToStringannotations,respectively.TheseannotationscauseLomboktogeneratetherespectivemethods,andtheyarecustomizablesothatyoucanspecifyfieldexclusionsandotherfactors.Bydefault,anynonstaticornontransientfieldsareincludedinthelogicthatisusedtocomposethesemethods.Theseannotationsusetheattributeexcludetospecifymethodsthatshouldnotbeincludedinthelogic.ThecallSuperattributeacceptsatrueorfalse,anditindicateswhethertousetheequals()methodofthesuperclasstoverifyequality.Thefollowingcodedemonstratestheuseoftheseannotations.
@EqualsAndHashCode
@ToString(exclude={"columnLabel"})
publicclassColumnBean{
privateBigDecimalid;
privateStringcolumnName;
privateStringcolumnLabel;
}
The@Dataannotationcanbeusedtoapplyfunctionalitybehindalltheannotationsdiscussedthusfarinthissection.Thatis,simplyannotatingaclasswith@DatacausesLomboktogenerategettersandsettersforeachofthenonstaticclassfieldsandaclassconstructor,aswellasthetoString(),equals(),andhashCode()methods.Italsocreatesaconstructorthatacceptsanyfinalfieldsorthoseannotatedwith@NonNullasarguments.Finally,itgeneratesdefaulttoString(),equals(),andhashCode()methodsthattakeallclassfieldsandmethodsintoconsideration.ThismakesthecodingofaPOJOveryeasy,anditismuchthesameassomealternativelanguages,suchasGroovy,thatoffersimilarfeatures.Listing1(alllistingsforthisarticlecanbefoundinJavaMagazine’sdownloadsection)showsthefullJavacodeforthePOJOthatisgeneratedbythefollowingcode:
@Data
publicclassColumnBean{
@NonNull
privateBigDecimalid;
@NonNull
privateStringcolumnName;
@NonNull
privateStringcolumnLabel;
}
Notethatifyoucreateyourowngettersorsetters,Lombokdoesnotgeneratethecodeeveniftheannotationsarepresent.Thiscanbehandyifyouwishtodevelopacustomgetterorsetterforoneormoreoftheclassfields.
Ifyouaremerelyinterestedinhavingconstructorsgeneratedautomatically,@AllArgsConstructorand@NoArgsConstructormightbeofuse.@AllArgsConstructorcreatesaconstructorfortheclassusingallthefieldsthathavebeendeclared.Ifafieldisaddedorremovedfromtheclass,thegeneratedconstructorisrevisedtoaccommodatethischange.Thisbehaviorcanbeconvenientforensuringthataclassconstructoralwaysacceptsvaluesforeachoftheclassfields.Thedisadvantageofusingthisannotationisthatreorderingtheclassfieldscausestheconstructorargumentstobereorderedaswell,whichcouldintroducebugsifthereiscodethatdependsuponthepositionofargumentswhengeneratingtheobject.@NoArgsConstructorsimplygeneratesano-argumentconstructor.
The@Valueannotationissimilartothe@Dataannotation,butitgeneratesanimmutableclass.Theannotationisplacedattheclasslevel,anditinvokestheautomaticgenerationofgettersforallprivatefinalfields.Nosettersaregenerated,andtheclassismarkedasfinal.Lastly,thetoString(),equals(),andhashCode()methodsaregenerated,andaconstructorisgeneratedthatcontainsargumentsforeachofthefields.
Can’tMyIDEDoThat?
Youmightbeaskingyourself,“Can’tmyIDEalreadydothatsortofrefactoring?”MostmodernIDEs—suchasNetBeans,Eclipse,andIntelliJ—offerfeaturessuchasencapsulationoffieldsandauto-generationofcode.Theseabilitiesaregreatbecausetheycansignificantlyincreaseproductivity.However,thesecapabilitiesdonotreducecodeclutter,sotheycanleadtorefactoringdowntheroad.Let’ssayyourJavaobjecthas10fields.ToconformtoaJavaBean,itwillcontain20accessormethods(onegetterandsetterpairperfield).That’salotofclutter.Also,whathappenswhenyoudecidetochangeoneofyourfieldnames?You’llhavetodosomerefactoringinordertochangeitcleanly.Ifyou’reusingLombok,yousimplychangethefieldnameandmoveonwithyourlife.
BuilderObjects
Sometimesitisusefultohavetheabilitytodevelopabuilderobject,whichallowsobjectstobeconstructedusingastep-by-steppatternwithcontrolledconstruction.Forexample,insomecaseslargeobjectsrequireseveralfieldstobepopulated,whichcanbeproblematicwhensuchanobjectisimplementedviaaconstructor.
LombokmakesitsimpletocreatebuilderobjectsinmuchthesamewaythatitenableseasyPOJOcreation.Annotatingaclasswith@Builderproducesaclassthatadherestothebuilderpattern—thatis,aninnerbuilderclassisproducedthatcontainseachoftheclassfields.(“Builder”isprecededbythenameoftheclass.SoaclassnamedFoohasaFooBuilderclassgenerated.)Thegeneratedbuilderclasscontainsa“setter”methodforeachoftheclassfields,butthenamesofthemethodsdonotincludetheusual“set”prefix.Themethodsthemselvessetthevaluethatispassedintothemethods,andthentheyreturnthebuilderobject.Listing2inthedownloadablecodedemonstratesaclassthatcontainsabuilder,andListing3demonstratesthesameobjectannotatedwith@Builder.
[email protected],theannotationcanbeplacedontheclass,onaconstructor,oronamethod.PlacingtheannotationonaconstructorproducesthesamebuilderobjectshowninListing2,butitgeneratesmethodsforeachoftheconstructor’sargumentsinthebuilder.Thismeansthatyoucanomitaclassfieldfromtheconstructor,oryoucanchoosetoincludeasuperclassfieldintheconstructor.Theonlywaytoincludesuperclassfieldsinabuilderisforanobjecttocontainasuperclass.
ThetoBuilderattributeofthe@Builderannotationacceptstrueorfalse,anditcanbeusedtodesignatewhetheratoBuilder()methodisincludedinthegeneratedbuilderobject.Thismethodcopiesthecontentsofanexistingobjectofthesametype.
Itispossibletotreatoneofthefieldsasabuildercollectionbyannotatingitwith@Singular.Thiscausestwoaddermethodstobegenerated—onetoaddasingleelementandanothertoaddallelements.Thisannotationalsocausesaclear()methodtobegenerated,whichclearsthecontentsofthecollection.
EasyCleanup
Lombokmakesiteasytocleanupresourcesaswell.Howoftenhaveyoueitherforgottentoclosearesourceorwrittenlotsofboilerplatetry-catchblockstoaccommodateresourceclosing?Thankstothe@Cleanupannotation,younolongerneedtoworryaboutforgettingtoreleasearesource.
AlthoughtheJavalanguagenowcontainsthetry-with-resourcesstatementtohelpcloseresources,@Cleanupcanbeausefulalternativeinsomecases,becauseitcausesatry-finallyblocktobegeneratedaroundthesubsequentcode,andthenitcallstheannotatedresource’sclose()method.Ifthecleanupmethodforagivenresourceisnotnamedclose(),thecleanupmethodnamecanbespecifiedwiththeannotation’svalueattribute.Listing4inthedownloadablecodedemonstratesablockofcodethatcontainssomelinestomanuallyclosetheresource.Listing5demonstratesthesameblockofcodeusing@Cleanup.
Itisimportanttonotethatinacasewherecodethrowsanexceptionandthensubsequentcodeinvokedvia@Cleanupalsothrowsanexception,theoriginalexceptionwillbehiddenbythesubsequentlythrownexception.
LockingSafely
Toensuresafetybyhavingonlyonethreadthatcanaccessaspecifiedmethodatatime,themethodshouldbemarkedassynchronized.Lomboksuppliesanevensaferwaytoensurethatonlyonethreadcanaccessamethodatatime:the@Synchronizedannotation.Thisannotationcanbeusedonlyonstaticandinstancemethods,justlikethesynchronizedkeyword.However,ratherthanlockingonthis,theannotationlocksonaprivatefieldnamed$lockfornonstaticmethodsandon$LOCKforstaticmethods.Thisfieldisauto-generatedifitdoesnotalreadyexist,oryoucancreateityourself.Youcanalsospecifyadifferentlockfieldbyspecifyingitasaparameterto@Synchronized.Thefollowingcodeillustratestheuseof@Synchronized:
@Synchronized
publicstaticvoidhelloLombok(){
System.out.println("Lombok");
}
Thissolutioncanbeasaferalternativetousingthesynchronizedkeyword,becauseitallowsyoutolockonaninstancefieldratherthanonthis.
EffortlessLogging
Mostloggingrequiressomedeclarationtosetupaloggerwithineachclass.Thiscodeisdefinitelyrepetitiveboilerplatecode.Lombokcantakecareoftheloggerdeclarationifyouplacethe@Logannotation(oranannotationpertainingtoyourchoiceofloggingAPI)onanyclassthatrequiresloggingcapability.
Forinstance,ifyouwishtousealoggingAPI—say,Log4j2—eachclassthatusestheloggermustdeclaresomethingsimilartothefollowing:
publicclassClassName(){
privatestaticfinalorg.apache.log4j.Loggerlog=
org.apache.log4j.Logger.getLogger(ClassName.class);
...
//Uselogvariableasneeded
}
Lombokmakesitpossibletodothefollowinginstead:
@Log4j2
publicclassClassName(){
...
//Uselogvariableasneeded
}
Listing6inthedownloadablecodeshowsanexampleusingLog4j2.Thenameoftheloggerwillautomaticallybethesameasitscontainingclass’name.However,thiscanbecustomizedbyspecifyingthetopicattributeoftherespectiveloggingannotation.ForacompletelistingofsupportedloggingAPIs,refertotheLombokdocumentationandtheLombokJavadoc.
OtherUsefulItems
ThereareseveralotherusefulfeaturesLombokoffersthatIhaven’tyetcovered.Let’sgothroughacoupleofthemosthighlyused.
Informaldeclaration.Thevalkeywordcanbeusedinplaceofanobjecttypewhenyoudeclarealocalfinalvariable,muchlikethevalkeywordthatyouhaveseeninalternativelanguagessuchasGroovyorJython.Takethefollowingcode,forinstance:
finalArrayList
延伸文章資訊
- 1Introduction to Project Lombok | Baeldung
A comprehensive and very practical introduction to many useful usecases of Project Lombok on stan...
- 2Project Lombok: Clean, Concise Java Code - Oracle
The Lombok library was created to make Java an easier language in which to code. It takes some of...
- 3Introduction to Project Lombok in Java and How to get started?
Project Lombok is a java library tool that is used to minimize/remove the boilerplate code and sa...
- 4Lombok Java - Javatpoint
The project Lombok is a popular and widely used Java library that is used to minimize or remove t...
- 5A Complete Guide to Lombok - Auth0
Project Lombok (from now on, Lombok) is an annotation-based Java library that allows you to reduc...