+ All Categories
Home > Documents > Java _ Java, SQL and JOOQ

Java _ Java, SQL and JOOQ

Date post: 11-Nov-2015
Category:
Upload: haoyuan-liu
View: 44 times
Download: 1 times
Share this document with a friend
Description:
about java, sql, and jooq
48
Java, SQL and jOOQ. Best Practices and Lessons Learned from Writing Awesome Java and SQL Code. Get some hands‑on insight on whatʹs behind developing jOOQ. Archive | java RSS for this section in java, sql Leave a comment jOOQ vs. Hibernate: When to Choose Which Hibernate has become a de‑facto standard in the Java ecosystem, and after the fact, also an actual JavaEE standard implementation if standards matter to you (http://xkcd.com/927), and if you put the JCP on the same level with ISO, ANSI, IEEE, etc. This article does not intended to discuss standards, but visions. Hibernate (http://hibernate.org) shares JPA’s vision of ORM. jOOQ (http://www.jooq.org) shares SQL’s vision of powerful querying, so for the sake of the argument, let’s use Hibernate / JPA / ORM interchangeably, much like jOOQ / JDBC / SQL. The question why should anyone not use Hibernate these days always shows up frequently (https://groups.google.com/forum/#!topic/jooq‑user/gmBf6g6sdQA) – precisely because Hibernate is a de‑ facto standard, and the first framework choice in many other frameworks such as Grails (which uses GORM, which again uses Hibernate (https://grails.github.io/grails‑doc/latest/guide/GORM.html)). However, even Gavin King, the creator of Hibernate, doesn’t believe that Hibernate should be used for everything: (https://plus.google.com/+GavinKing/posts/LGJU1NorAvY) If that’s the case, are there any objective decision helping points that you could consider, when to use an ORM and when to use SQL? Discussing on a high level March 24, 2015
Transcript
  • 3/24/2015 java|Java,SQLandjOOQ.

    http://blog.jooq.org/category/java/ 1/48

    Java,SQLandjOOQ.

    BestPracticesandLessonsLearnedfromWritingAwesomeJavaandSQLCode.GetsomehandsoninsightonwhatsbehinddevelopingjOOQ.

    Archive|javaRSSforthissection

    injava,sqlLeaveacomment

    jOOQvs.Hibernate:WhentoChooseWhich

    HibernatehasbecomeadefactostandardintheJavaecosystem,andafterthefact,alsoanactualJavaEEstandardimplementationifstandardsmattertoyou(http://xkcd.com/927),andifyouputtheJCPonthesamelevelwithISO,ANSI,IEEE,etc.

    Thisarticledoesnotintendedtodiscussstandards,butvisions.Hibernate(http://hibernate.org)sharesJPAsvisionofORM.jOOQ(http://www.jooq.org)sharesSQLsvisionofpowerfulquerying,soforthesakeoftheargument,letsuseHibernate/JPA/ORMinterchangeably,muchlikejOOQ/JDBC/SQL.

    ThequestionwhyshouldanyonenotuseHibernatethesedaysalwaysshowsupfrequently(https://groups.google.com/forum/#!topic/jooquser/gmBf6g6sdQA)preciselybecauseHibernateisadefactostandard,andthefirstframeworkchoiceinmanyotherframeworkssuchasGrails(whichusesGORM,whichagainusesHibernate(https://grails.github.io/grailsdoc/latest/guide/GORM.html)).

    However,evenGavinKing,thecreatorofHibernate,doesntbelievethatHibernateshouldbeusedforeverything:

    (https://plus.google.com/+GavinKing/posts/LGJU1NorAvY)

    Ifthatsthecase,arethereanyobjectivedecisionhelpingpointsthatyoucouldconsider,whentouseanORMandwhentouseSQL?

    Discussingonahighlevel

    March24,2015

  • 3/24/2015 java|Java,SQLandjOOQ.

    http://blog.jooq.org/category/java/ 2/48

    Firstoff,letsbringthisdiscussiontoahigherlevel.InsteadofdecidingbetweenHibernateandjOOQasconcreteimplementationsoftheirowndomains,letsthinkaboutORMvs.SQL,andtheirdifferentusecases.

    WhendecidingbetweenanORM(e.g.Hibernate)andSQL(e.g.jOOQ),thedrivingquestionthatyoushouldaskyourselfisnotthequestionofprojectcomplexity.SomeofourmostdemandingcustomersareusingjOOQonmediumsizedschemaswiththousandsoftables/views.Often,thoseschemasareextremelynormalisedandsometimesevendeployedonasmanyassixdifferentRDBMS.jOOQwasspecificallydesignedtoworkinthesescenarios,whilekeepingthesimpleusecaseinmindaswell.

    So,insteadofthinkingaboutprojectcomplexity,askyourselfthefollowingquestions:

    1.Willyourdatamodeldriveyourapplicationdesign,orwillyourapplicationdesigndriveyourdatamodel(s)?Amainaspecthereisthequestionwhetheryoucareaboutyourdatabaseinthesenseofwhetheritmightsurviveyourapplication.Veryoften,applicationscomeandgo.TheymayberewritteninPython/JavaScript,etc.5yearsdowntheline.Oryouhavemultipleapplicationsaccessingthesamedatabase:YourJavaapplication,somePerlscripts,storedprocedures,etc.Ifthisisthecase,databasedesignisapriorityinyourproject,andjOOQworksextremelywellinthesesetups.

    IfyoudontnecessarilycareaboutyourdatabaseinthesensethatyoujustwanttopersistyourJavadomainsomewhere,andthishappenstobearelationaldatabase,thenHibernatemightbeabetterchoiceatleastinearlystagesofyourproject,becauseyoucaneasilygenerateyourdatabaseschemafromyourEntitymodel.

    2.Willyoudomostlycomplexreadingandsimplewriting,orwillyouengageincomplexwriting?SQLreallyshineswhenreadingiscomplex.Whenyoujoinmanytables,whenyouaggregatedatainyourdatabase,whenyoudoreporting,whenyoudobulkreadingandwriting.Youthinkofyourdataintermsofsettheory,e.g.yourdataasawhole.WritingCRUDwithSQLisboring,though.ThisiswhyjOOQalsoprovidesyouwithanActiveRecordstyleAPIthathandlestheboringparts,whenyoureoperatingonsingletables(Jasonmentionedthis).

    If,however,yourwritingbecomescomplex,i.e.youhavetoloadacomplexobjectgraphwith20entitiesinvolvedintomemory,performoptimisticlockingonit,modifyitinmanydifferentwaysandthenpersistitagaininonego,thenSQL/jOOQwillnothelpyou.ThisiswhatHibernatehasoriginallybeencreatedfor.

    Opinion

    Ibelievethatdataisforever.Youshould*always*assumethatyourdatabasesurvivesyourapplication.Itismucheasiertorewrite(partsof)anapplicationthantomigrateadatabase.Havingacleanandwelldesigneddatabaseschemawillalwayspayoffdownthelineofaproject,specificallyofacomplexproject.Seealsoourpreviousarticleaboutthefallacyofschemalessdatabases(http://blog.jooq.org/2014/10/20/stopclaimingthatyoureusingaschemalessdatabase/).

    Also,mostprojectsreallydo90%readingand10%writing,writingoftennotbeingcomplex(23tablesmodifiedwithinatransaction).Thismeansthatmostofthetime,thecomplexitysolvedbyHibernate/JPAsfirstandsecondlevelcachesisnotneeded.Peopleoftenmisunderstandthesefeaturesandsimplyturnoffcaching,flushingHibernatescachetotheserverallthetime,andthususingHibernateinthewrongway.

  • 3/24/2015 java|Java,SQLandjOOQ.

    http://blog.jooq.org/category/java/ 3/48

    If,however,youreundecidedabouttheabovetwoaxesofdecision,youcangothemiddlewayandusejOOQonlyforreporting,batchprocessing,etc.anduseHibernateforyourCRUDinaCQRS(CommandQueryResponsibilitySegregation:http://martinfowler.com/bliki/CQRS.html(http://martinfowler.com/bliki/CQRS.html))style.TherearealsoquiteafewjOOQuserswhohavechosenthispath.

    Furtherreading

    Throughputvs.ComplexityWhenshouldIuseanORM?(http://mikehadlow.blogspot.ca/2012/06/whenshouldiuseorm.html)byMikeHadlowWhyshouldyouuseanORM?(http://karwin.blogspot.ch/2009/01/whyshouldyouuseorm.html)byBillKarwinArethereanygoodreasonsnottouseanORM?(http://stackoverflow.com/q/194147/521799)onStackOverflowWhyshouldyouuseanORM?(http://stackoverflow.com/q/448684/521799)onStackOverflow

    injava,java82Comments

    10JavaArticlesEveryoneMustRead

    Onemonthago,wevepublishedalistof10SQLArticlesEveryoneMustRead(http://blog.jooq.org/2015/02/13/10sqlarticleseveryonemustread/).AlistofarticlesthatwebelievewouldaddexceptionalvaluetoourreadersonthejOOQblog(http://blog.jooq.org).ThejOOQblogisablogfocusingonbothJavaandSQL,soitisonlynaturalthattoday,onemonthlater,werepublishinganequallyexcitinglistof10Javaarticleseveryonemustread.

    Notethatbymustread,wemaynotspecificallymeantheparticularlinkedarticleonly,butalsootherworksfromthesameauthors,whohavebeenregularbloggersoverthepastyearsandneverfailedtoproducenewinterestingcontent!

    Heregoes

    1.BrianGoetz:Stewardship:theSoberingParts

    ThefirstblogpostisactuallynotablogpostbutarecordingofaveryinterestingtalkbyBrianGoetzonOraclesstewardshipofJava.OnthejOOQblog,wevebeenslightlycriticalabout12featuresoftheJavalanguageinthepast,e.g.whencomparingittoScala(http://blog.jooq.org/2014/08/01/the10mostannoying

    March13,2015

  • 3/24/2015 java|Java,SQLandjOOQ.

    http://blog.jooq.org/category/java/ 4/48

    thingscomingbacktojavaaftersomedaysofscala/),orCeylon(http://blog.jooq.org/2013/12/03/top10ceylonlanguagefeaturesiwishwehadinjava/).

    BrianmakesgoodpointsaboutwhyitwouldnotbeagoodideaforJavatobecomejustasmodernasquicklyasotherlanguages.AmustwatchforeveryJavadeveloper(around1h)

    2.AlekseyShipilv:TheBlackMagicof(Java)MethodDispatch

    Inrecentyears,theJVMhasseenquiteafewimprovements,includinginvokedynamicthatarrivedinJava7asaprerequisiteforJava8lambdas,aswellasagreattoolforother,moredynamiclanguagesbuiltontopoftheJVM,suchasNashorn(http://blog.jooq.org/2014/06/06/java8fridayjavascriptgoessqlwithnashornandjooq/).

    invokedynamicisonlyasmall,highlevelpuzzlepieceintheadvancedtrickeryperformedbytheJVM.Whatreallyhappensunderthehoodwhenyoucallmethods?Howaretheyresolved,optimisedbytheJIT?Alekseysarticlesubtitlerevealswhatthearticleisreallyabout:

    EverythingyouwantedtoknowaboutBlackDeviouslySurreptitiousMagicinlowlevelperformanceengineering

    Definitelynotasimpleread,butagreatposttolearnaboutthepoweroftheJVM.

    ReadAlekseysTheBlackMagicof(Java)MethodDispatch(http://shipilev.net/blog/2015/blackmagicmethoddispatch/)

    3.OliverWhite:JavaToolsandTechnologiesLandscapefor2014

  • 3/24/2015 java|Java,SQLandjOOQ.

    http://blog.jooq.org/category/java/ 5/48

    Werealreadyin2015,butthisreportbyOliverWhite(atthetimeheadofZeroTurnaroundsRebelLabs(http://zeroturnaround.com/rebellabs/))hadbeenexceptionallywellexecutedandtouchesprettymucheverythingrelatedtotheJavaecosystem.

    ReadOliversJavaToolsandTechnologiesLandscapefor2014(http://zeroturnaround.com/rebellabs/javatoolsandtechnologieslandscapefor2014/)

    4.PeterLawrey:JavaLambdasandLowLatency

    WhenAlekseyhasintroducedustosomeperformancesemanticsintheJVM,Petertakesthisonestepfurther,talkingaboutlowlatencyinJava8.WecouldhavepickedmanyotherusefullittleblogpostsfromPetersblog,whichisallaboutlowlatency,highperformancecomputingontheJVM,sometimesevendoingadvancedoffheaptrickery.

    ReadPetersJavaLambdasandLowLatency(http://vanillajava.blogspot.ch/2015/01/javalambdasandlowlatency.html)

    5.NicolaiParlog:EverythingYouNeedToKnowAboutDefaultMethods

    NicolaiisanewcomerintheJavablogosphere,andaverypromisingone,too.HiswellresearchedarticlesgoindepthaboutsomeinterestingfactsrelatedtoJava8,diggingoutoldemailsfromtheexpertgroupsmailinglist,explainingthedecisionstheymadetoconcludewithwhatwecallJava8today.

    ReadNicolaisEverythingYouNeedToKnowAboutDefaultMethods(http://blog.codefx.org/jdk/everythingaboutdefaultmethods/)

    6.LukasEder:10ThingsYouDidntKnowAboutJava

    ThislistwouldntbecompletewithoutlistinganotherlistthatwewroteourselvesonthejOOQblog.Javaisanoldbeastwith20yearsofhistorythisyearin2015.Thisoldbeasthasalotofsecretsandcaveatsthatmanypeoplehaveforgottenorneverthoughtabout.Weveuncoveredthemforyou:

    ReadLukass10ThingsYouDidntKnowAboutJava(http://blog.jooq.org/2014/11/03/10thingsyoudidntknowaboutjava/)

  • 3/24/2015 java|Java,SQLandjOOQ.

    http://blog.jooq.org/category/java/ 6/48

    7.EdwinDalorzo:WhyThereIsInterfacePollutioninJava8

    Edwinhasbeenrespondingtoourownblogpostsacoupleoftimesinthepastwithverywellresearchedandthoroughlythoughtthrougharticles,inparticularaboutJava8relatedfeatures,e.g.comparingJava8StreamswithLINQ(http://blog.informatech.cr/2013/03/24/javastreamspreviewvsnetlinq/)(somethingthatwevedoneourselves,aswell(http://blog.jooq.org/2013/11/02/doesjava8stillneedlinqorisitbetterthanlinq/)).

    ThisparticulararticleexplainswhytherearesomanydifferentanddifferentlynamedfunctionalinterfacesinJava8.

    ReadEdwinsWhyThereIsInterfacePollutioninJava8(http://blog.informatech.cr/2014/04/04/jdk8interfacepollution/)

    8.VladMihalcea:HowDoesPESSIMISTIC_FORCE_INCREMENTLockModeWork

    WhenJavatalkstodatabases,manypeopledefaulttousingHibernateforconvenience(seealso3.OliverWhite:JavaToolsandTechnologiesLandscapefor2014(http://zeroturnaround.com/rebellabs/javatoolsandtechnologieslandscapefor2014/)).Hibernatesmainvision,however,isnottoaddconvenienceyoucangetthatinmanyotherwaysaswell(http://www.hibernatealternative.com/).HibernatesmainvisionistoprovidepowerfulmeansofnavigatingandpersistinganobjectgraphrepresentationofyourRDBMSsdatamodel,includingvariouswaysoflocking.

    VladisanextremelyproficientHibernateuser,whohasawholeblogseriesonhowHibernateworksgoing.Wevepickedarecent,wellresearchedarticleaboutlocking,butwestronglysuggestyoureadtheotherarticlesaswell:

    ReadVladsHowDoesPESSIMISTIC_FORCE_INCREMENTLockModeWork(http://vladmihalcea.com/2015/02/16/hibernatelockingpatternshowdoespessimistic_force_incrementlockmodework/)

    9.PetriKainulainen:WritingCleanTests

    ThisisntapurelyJavarelatedblogpost,althoughitiswrittenfromtheperspectiveofaJavadeveloper.Moderndevelopmentinvolvestestingautomatictestingandlotsofit.PetrihaswrittenaninterestingblogseriesaboutwritingcleantestsinJavayoushouldntmisshisarticles!

    ReadPetrisWritingCleanTests(http://www.petrikainulainen.net/writingcleantests/)

  • 3/24/2015 java|Java,SQLandjOOQ.

    http://blog.jooq.org/category/java/ 7/48

    10.EugenParaschiv:Java8ResourcesCollection

    Ifyoudontalreadyhaveatleast9opentabswithinterestingstufftoreadafterthislist,getreadyforabrowsertabexplosion!EugenParaschivwhomaintainsbaeldung.com(http://baeldung.com)hasbeencollectingallsortsofveryinterestingresourcesrelatedtoJava8inasinglelinkcollection.Youshoulddefinitelybookmarkthiscollectionandcheckbackfrequentlyforinterestingchanges:

    ReadEugensJava8ResourcesCollection(http://www.baeldung.com/java8)

    Manyotherarticles

    Thereare,ofcourse,manyotherverygoodarticlesprovidingdeepinsightintousefulJavatricks.Ifyoufindyouveencounteredanarticlethatwouldnicelycomplementthislist,pleaseleavealinkanddescriptioninthecommentssection.Futurereaderswillappreciatetheadditionalinsight.

    injava,opensourceLeaveacomment

    YakShavingisaGoodWaytoImproveanAPI

    YakShaving(uncountable)(http://en.wiktionary.org/wiki/yak_shaving):

    1. (idiomatic)Anyapparentlyuselessactivitywhich,byallowingyoutoovercomeintermediatedifficulties,allowsyoutosolvealargerproblem.

    2. (idiomatic)Alessusefulactivitydonetoconsciouslyorunconsciouslyprocrastinateaboutalargerbutmoreusefultask.

    BothinterpretationsofthetermYakShavingasexplainedbyWiktionary(http://en.wiktionary.org/wiki/yak_shaving)areabsolutelyaccuratedescriptionsofmostrefactoringjobs.TheYakShavinginrefactoringitselfcanbedescribedbythisgifshowingwhathappenswhenyouwanttochangealightbulb:

    March9,2015

  • 3/24/2015 java|Java,SQLandjOOQ.

    http://blog.jooq.org/category/java/ 8/48

    (http://imgur.com/gallery/t0XHtgJ)

    However,whendevelopinganAPI,itsnotsuchabadideatoperformactualYakShaving(onlythefirstinterpretation,ofcourse).Letslookatanexamplewhy,fromthedailyworkmaintainingjOOQ(http://www.jooq.org).

    TheTask

    ForjOOQ3.6,Iwantedtoimplementaverysimplefeature.Feature#2639:AddstoredprocedureOUTvaluestoDEBUGlogoutput(https://github.com/jOOQ/jOOQ/issues/2639).Thisisnotanimportantfeatureatall,butcertainlyveryusefultoalotofjOOQusers.TheideaisthateverytimeyourunastoredprocedurewithDEBUGloggingactivated,youllgettheOUTparametersloggedalongwiththeprocedurecall.Heresavisualisation:

    (https://lukaseder.files.wordpress.com/2015/03/debuglog.png)

    Now,theactualimplementationwouldhavebeenveryeasy.Justabout10linesofcodeintheexistingLoggerListener(http://www.jooq.org/javadoc/latest/org/jooq/tools/LoggerListener.html)thatalreadytakescareofloggingalltheotherthings.Buttherewereacoupleofcaveats,whichremindedmeoftheabovelightbulbchanginggif:

    Theapparentlyuselessactivities

    1. TherewasnowaytoaccesstheRETURN_VALUEmetainformationofajOOQRoutine(http://www.jooq.org/javadoc/latest/org/jooq/Routine.html)

  • 3/24/2015 java|Java,SQLandjOOQ.

    http://blog.jooq.org/category/java/ 9/48

    2. TherewasnoeasywaytoaccessRoutineINandOUTvaluesgenerically3. TherewaslifecycleeventthatmodelledthemomentwhenOUTparametersarefetchedinjOOQ4. TherewasnowaytoformatRoutineOUTparametersinaniceway

    Doesthisfeelfamiliar?Thereisneedforrefactoring!

    Do you know that feeling? When you're implementing a really small change and suddenly, in order to implement it nicely, you have 20 changes?

    Lukas Eder @lukaseder

    @lukaseder Someone sent this to me to explain it. pic.twitter.com/ZBr06UlAir9:11 AM 2 Mar 2015

    Jason Herr @herr_jason

    Follow

    1 RETWEET 2 FAVORITES

    02 Mar

    Now,thiswholeimplementationishiddeninjOOQsinternals.Itwouldntmattertoomuchforusers,ifthishadbeenhackedtogetherinonewayoranother.Forinstance,obviouslytheRETURN_VALUEmetainformationcouldbeaccessedthroughinternalrefactorings,thesameistrueforINandOUTvalues.Thereareotherlifecycleeventsthatmighthaveworkedjustaswell,andformattingiseasytoreimplement.

    ButthisisapopularAPIthatisusedbymanyuserswhomightprofitfromacleanersolution.Thus,whydontwesimplyrefactorandimplement:

    1. AddapublicRoutine.getReturnParameter()method(https://github.com/jOOQ/jOOQ/issues/4107)2. AddpublicRoutine.getValue()andsetValue()methods(https://github.com/jOOQ/jOOQ/issues/3748)3. AddExecuteListener.outStart(ExecuteContext)andoutEnd(ExecuteContext)tocapturefetchingof

    RoutineOUTparameters(https://github.com/jOOQ/jOOQ/issues/4108)4. AddRoutine.outRecord()andRoutine.inRecord()toviewaRoutineasaRecord

    (https://github.com/jOOQ/jOOQ/issues/4109)

    Thethingis:

  • 3/24/2015 java|Java,SQLandjOOQ.

    http://blog.jooq.org/category/java/ 10/48

    TheAPIimplementoristhefirstAPIconsumer

    ItshardtoforeseewhatAPIusersreallywant.ButifyoureimplementinganAPI(orjustafeature),andyoudiscoverthatsomethingismissing,alwaysconsideraddingthatmissingthingtothepublicAPI.Ifitcouldbeusefultoyourself,internally,itcouldbeevenmoreusefultomanyothers.Thisway,youturnonelittlenicefeatureinto5,amplifyingtheuserlove.

    Dontgetmewrong.Thisdoesntmeanthateverylittlepieceoffunctionalityneedstobeexposedpublicly,aucontraire.Butthefactthatsomethingiskeepingyouasthemaintainerfromwritingcleancodemightindicatethatothersimplementthesamehackyworkaroundsasyou.Andtheywontaskyouexplicitlyforit!

    Dontbelieveit?Heresanentirelysubjectiveanalysisofuserfeedback:

    0.2%Hey,thisisacoolproduct,Iwanttohelptheownermakeitbetter,Illprovideaverydescriptive,constructivefeaturerequestandengageforthenext5weekstohelpimplementit.0.8%Whateverdudes.Makethiswork.Please.1.3%Whateverdudes.Makethiswork.ASAP!4.0%WTFiswrongwithyouguys?Didntyouatleastthinkaboutthisonce??4.7%OK,Imgoingtowritethiscompletelyuninformedrantaboutthisproductnow,whichIhatesomuch.Itmakesmylifecompletelymiserable9.0%Ohwell,thisdoesntwork.Letsgohome,its17:00anyways80.0%Ohwell,thisdidntworkyesterdayalready.Letsgohome.ItsFriday,16:00anyways

    Now,mostofthislistwasntmeantentirelyseriously,butyougetthepoint.Theremaybethose0.2%ofusers/customersthatloveyouandthatactivelyengagewithyou.Othersmaystillloveyouoratleastlikeyou,buttheywontengage.Youhavetoguesstimatewhattheyneed.

    So.Bottomline:

    Ifyouneedit,theyprobablyneedit.StartYakShaving!

    injavaLeaveacomment

    TheJavaLegacyisConstantlyGrowing

    IverecentlystumbleduponaveryinterestingcaveatoftheJDKAPIs,theClass.getConstructors()(http://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#getConstructors)method.Itsmethodsignatureisthis:

    Constructor[]getConstructors()

    March5,2015

  • 3/24/2015 java|Java,SQLandjOOQ.

    http://blog.jooq.org/category/java/ 11/48

    TheinterestingthinghereisthatClass.getConstructor(Class...)(http://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#getConstructorjava.lang.Class...)returnsaConstructor,withbeingmaintained:

    ConstructorgetConstructor(Class...parameterTypes)

    Whyisthereadifference,i.e.whydoesntthefirstmethodreturnConstructor[]?

    LetsconsidertheJavadoc:

    NotethatwhilethismethodreturnsanarrayofConstructorobjects(thatisanarrayofconstructorsfromthisclass),thereturntypeofthismethodisConstructor[]andnotConstructor[]asmightbeexpected.Thislessinformativereturntypeisnecessarysinceafterbeingreturnedfromthismethod,thearraycouldbemodifiedtoholdConstructorobjectsfordifferentclasses,whichwouldviolatethetypeguaranteesofConstructor[].

    Thatsatoughone.Historically,hereshowthishappened:

    Java1.0/Oak:Arrays

    InJava1.0(theimmediatesuccessoroftheOakprogramminglanguage(https://en.wikipedia.org/wiki/Oak_(programming_language))),arrayswerealreadyintroduced.Infact,theyhavebeenintroducedbeforethecollectionsAPI,whichwasintroducedinJava1.2.Arrayssufferfromalltheproblemsthatweknowtoday,includingthembeingcovariant,whichleadstoalotofproblemsatruntime,thatcannotbecheckedatcompiletime:

    Object[]objects=newString[1];objects[0]=Integer.valueOf(1);//Ouch

  • 3/24/2015 java|Java,SQLandjOOQ.

    http://blog.jooq.org/category/java/ 12/48

    Java1.1:ReflectionAPI

    ShortofadecentcollectionsAPI,theonlypossiblereturntypeoftheClass.getConstructors()methodwasConstructor[].Areasonabledecisionatthetime.Ofcourse,youcoulddothesamemistakeasabove:

    Object[]objects=String.class.getConstructors();objects[0]=Integer.valueOf(1);//Ouch

    butintheadditiontotheabove,youcouldalso,rightfully,writethis:

    Constructor[]constructors=String.class.getConstructors();constructors[0]=Object.class.getConstructor();

    //Muahahahahahahaha

    Java1.2:CollectionsAPI

    Javahasbeenbackwardscompatiblefromtheveryearlydays,evenfromOakonwards.TheresaveryinterestingpieceofhistoricresearchaboutsomeofOaksbackwardscompatibilityhavingleakedintoJavatothisdateinthisStackOverflowquestion(http://stackoverflow.com/a/7202659/521799).

    WhileitwouldhavebeennaturaltodesignthereflectionAPIusingcollections,now,itwasalreadytoolate.Abettersolutionmightvebeen:

    ListgetConstructors()

    However,notethatwedidnthavegenericsyet,sothearrayactuallyconveysmoretypeinformationthanthecollection.

    Java1.5:Generics

    InJava5,thechangefrom

    Constructor[]getConstructors()

    to

    Constructor[]getConstructors()

    hasbeenmadeforthereasonsmentionedabove.Now,thealternativeAPIusingacollectionwoulddefinitelyhavebeenbetter:

    ListgetConstructors()

  • 3/24/2015 java|Java,SQLandjOOQ.

    http://blog.jooq.org/category/java/ 13/48

    Buttheshiphassailed.

    Java,theuglywart

    Javaisfulloftheselittlecaveats.TheyrealldocumentedintheJavadocs,andoftenonStackOverflow.Justyesterday,wevedocumentedanewcaveatrelatedtocompletelynewAPIinMapandConcurrentHashMap(http://blog.jooq.org/2015/03/04/avoidrecursioninconcurrenthashmapcomputeifabsent/).

    Stewardship:theSoberingParts,averygoodtalkaboutallthosecaveatsandhowharditistomaintainthembyBrianGoetzcanbeseenhere:

    Thesummaryofthetalk:

    (https://www.youtube.com/watch?v=2y5Pv4yN0b0)

    Whenlanguagedesignerstalkaboutthelanguagetheyredesigning

  • 3/24/2015 java|Java,SQLandjOOQ.

    http://blog.jooq.org/category/java/ 14/48

    injava,sqlLeaveacomment

    jOOQEinalternativerWegmitJavaundSQLzuarbeiten

    WevepublishedanarticleintheGermanmagazinewww.javaaktuell.de(http://www.ijug.eu/javaaktuell/dasmagazin.html),whichispublishedbytheiJUGe.V.(http://www.ijug.eu/).

    Youcanreadanddownloadthearticlefreeofchargefromourblog!(https://lukaseder.files.wordpress.com/2015/03/022015javaaktuelllukasederjooqeinalternativerwegmitjavaundsqlzuarbeiten.pdf)

    InJavagibteskeinStandardAPI,dasdieAusdrucksstrkeundMchtigkeitvonSQLdirektuntersttzt.AlleAufmerksamkeitistaufobjektrelationalesMappingundanderehhereAbstraktionslevelgerichtet,beispielsweiseOQL,HQL,JPQL,CriteriaQuery.jOOQisteinduallizenziertesOpenSourceProdukt,dasdieseLckefllt.EsimplementiertSQLalstypsicheredomnenspezifischeSprachedirektinJavaundisteineguteWahlfrJavaApplikationen,indenenSQLundherstellerspezifischeDatenbankfunktionalittwichtigsind.Eszeigt,wieeinemodernedomnenspezifischeSprachedieEntwicklerproduktivittstarkerhhenkann,indemSQLdirektinJavaeingebettetist.

    March2,2015

  • 3/24/2015 java|Java,SQLandjOOQ.

    http://blog.jooq.org/category/java/ 15/48

    iJUGJavaAktuell[Februar2015]LukasEderjOOQeinalternativerWegmitJavaundSQLzuarbeiten(https://www.slideshare.net/LukasEder1/ijugjavaaktuellfebruar2015lukasederjooqeinalternativerwegmitjavaundsqlzuarbeiten)fromLukasEder(http://www.slideshare.net/LukasEder1)

    injava,scalaLeaveacomment

    jOOQvs.SlickProsandConsofEachApproach

    Everyframeworkintroducesanewcompromise.Acompromisethatisintroducedbecausetheframeworkmakessomeassumptionsabouthowyoudliketointeractwithyoursoftwareinfrastructure.

    AnexampleofwherethiscompromisehasstruckusersrecentlyisthediscussionAreSlickqueriesgenerallyisomorphictotheSQLqueries?(https://groups.google.com/d/msg/scalaquery/K2tch9yxx60/QB055F0pn3gJ).And,ofcourse,theansweris:No.WhatappearstobeasimpleSlickquery:

    February24,2015

  • 3/24/2015 java|Java,SQLandjOOQ.

    http://blog.jooq.org/category/java/ 16/48

    valsalesJoin=salesjoinpurchasersjoinproductsjoinsupplierson{case(((sale,purchaser),product),supplier)=>sale.productId===product.id&&sale.purchaserId===purchaser.id&&product.supplierId===supplier.id}

    turnsintoaratherlargemonsterwithtonsofderivedtablesthataretotallyunnecessary,giventheoriginalquery(formattingismine):

    selectx2.x3,x4.x5,x2.x6,x2.x7from(selectx8.x9asx10,x8.x11asx12,x8.x13asx14,x8.x15asx7,x8.x16asx17,x8.x18asx3,x8.x19asx20,x21.x22asx23,x21.x24asx25,x21.x26asx6from(selectx27.x28asx9,x27.x29asx11,x27.x30asx13,x27.x31asx15,x32.x33asx16,x32.x34asx18,x32.x35asx19from(selectx36."id"asx28,x36."purchaser_id"asx29,x36."product_id"asx30,x36."total"asx31from"sale"x36)x27innerjoin(selectx37."id"asx33,x37."name"asx34,x37."address"asx35 from"purchaser"x37)x32on1=1)x8innerjoin(

  • 3/24/2015 java|Java,SQLandjOOQ.

    http://blog.jooq.org/category/java/ 17/48

    selectx38."id"asx22,x38."supplier_id"asx24,x38."name"asx26from"product"x38)x21on1=1)x2innerjoin(selectx39."id"asx40,x39."name"asx5,x39."address"asx41from"supplier"x39)x4on((x2.x14=x2.x23)and(x2.x12=x2.x17))and(x2.x25=x4.x40)wherex2.x7>=?

    ChristopherVogt,aformerSlickmaintainerandstillactivelyinvolvedmemberoftheSlickcommunity,explainstheaboveinthefollowingwords:

    ThismeansthatSlickreliesonyourdatabasesqueryoptimizertobeabletoexecutethesqlquerythatSlickproducedefficiently.CurrentlythatisnotalwaysthecaseinMySQL

    OneofthemainideasbehindSlick,accordingtoChristopher,is:

    SlickisnotaDSLthatallowsyoutobuildexactlyspecifiedSQLstrings.SlicksScalaquerytranslationallowsforreuseandcompositionandusingScalaasthelanguagetowriteyourqueries.Itdoesnotallowyoutopredicttheexactsqlquery,onlythesemanticsandtheroughstructure.

    Slickvs.jOOQ

    SinceChristopherlateronalsocomparedSlickwithjOOQ,Iallowedmyselftochimeinandtoaddmytwocents:

    Fromahighlevel(withoutactualSlickexperience)IdsaythatSlickandjOOQembracecompositionalityequally

  • 3/24/2015 java|Java,SQLandjOOQ.

    http://blog.jooq.org/category/java/ 18/48

    Fromahighlevel(withoutactualSlickexperience)IdsaythatSlickandjOOQembracecompositionalityequallywell.Iveseencrazyqueriesofseveral100soflinesof[jOOQ]SQLincustomercode,composedoverseveralmethods.YoucandothatwithbothAPIs.

    Ontheotherhand,asChrissaid:SlickhasafocusonScalacollections,jOOQonSQLtables.

    Fromaconceptualperspective(=intheory),thisfocusshouldntmatter.Fromatypesafetyperspective,ScalacollectionsareeasiertotypecheckthanSQLtablesandqueriesbecauseSQLasalanguageitselfisratherhardtotypecheckgiventhatthesemanticsofvariousoftheadvancedSQLclausesaltertypeconfigurationsratherimplicitly(e.g.outerjoins,groupingsets,pivotclauses,unions,groupby,etc.).Fromapracticalperspective,SQLitselfisonlyanapproximationoftheoriginalrelationaltheoriesandhasattainedalifeofitsown.Thismayormaynotmattertoyou.

    IguessintheenditreallyboilsdowntowhetheryouwanttoreasonaboutScalacollections(queriesarebetterintegrated/moreidiomaticwithyourclientcode)oraboutSQLtables(queriesarebetterintegrated/moreidiomaticwithyourdatabase).

    Atthispoint,Idliketoaddanothertwocentstothediscussion.Customersdontbuytheproductthatyoureselling.Theyneverdo.InthecaseofHibernate,customersanduserswerehopingtobeabletoforgetSQLforever.Theoppositeistrue.AsGavinKinghimself(thecreatorofHibernate)hadtoldme:

    (https://plus.google.com/+GavinKing/posts/LGJU1NorAvY)

    BecausecustomersandusershadneverlistenedtoGavin(andtootherORMcreators),wenowhavewhatmanycalltheobjectrelationalimpedancemismatch(https://en.wikipedia.org/wiki/Objectrelational_impedance_mismatch).AlotofunjustifiedcriticismhasbeenexpressedagainstHibernateandJPA,APIswhicharesimplytoopopularforthelimitedscopetheyreallycover.

    WithSlick(orC#sLINQ,forthatmatter(http://blog.jooq.org/2013/11/02/doesjava8stillneedlinqorisitbetterthanlinq/)),asimilarmismatchisimpedingintegrations,ifusersabusethesetoolsforwhattheybelievetobeareplacementforSQL.SlickdoesagreatjobatmodellingtherelationalmodeldirectlyintheScalalanguage.Thisiswonderfulifyouwanttoreasonaboutrelationsjustlikeyoureasonaboutcollections.ButitisnotaSQLAPI.Toillustratehowdifficultitistoovercometheselimitations,youcanbrowsetheissuetrackerorusergrouptolearnabout:

    Unwantedderivedtables(https://github.com/slick/slick/issues/623)Limitedsupportforouterjoin(https://groups.google.com/forum/#!topic/scalaquery/Uv9C0QPhYFI)

    Wellsimplycallthis:

    TheFunctionalRelationalImpedanceMismatch

    SQLismuchmore

  • 3/24/2015 java|Java,SQLandjOOQ.

    http://blog.jooq.org/category/java/ 19/48

    MarkusWinand(theauthorofthepopularSQLPerformanceExplained(http://sqlperformanceexplained.com/l))hasrecentlypublishedaverygoodpresentationaboutmodernSQL,anideathatwefullyembraceatjOOQ:

    ModernSQLinPostgreSQL(https://www.slideshare.net/MarkusWinand/modernsql)fromMarkusWinand(http://www.slideshare.net/MarkusWinand)WebelievethatAPIsthathavebeentryingtohidetheSQLlanguagefromgeneralpurposelanguageslikeJava,Scala,C#aremissingoutonalotoftheverynicefeaturesthatcanaddtremendousvaluetoyourapplication.jOOQisanAPIthatfullyembracestheSQLlanguage,withallitsawesomefeatures(andwithallitsquirks).Youobviouslymayormaynotagreewiththat.

    Wellleavethisarticleopenended,hopingyoullchimeintodiscussthebenefitsandcaveatsofeachapproach.OfstayingclosetoScalavs.stayingclosetoSQL.

    Asasmallteaser,however,Idliketoannounceafollowuparticleshowingthatthereisnosuchthingasanobjectrelationalimpedancemismatch.You(andyourORM)arejustnotusingSQLcorrectly.Staytuned!

    injavaLeaveacomment

    ThouShaltNotNameThyMethodEquals

    (unlessyoureallyoverrideObject.equals()(http://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#equalsjava.lang.Object),ofcourse).

    IvestumbleduponarathercuriousStackOverflowquestion(http://stackoverflow.com/q/28563304/521799)

    February18,2015

  • 3/24/2015 java|Java,SQLandjOOQ.

    http://blog.jooq.org/category/java/ 20/48

    IvestumbleduponarathercuriousStackOverflowquestion(http://stackoverflow.com/q/28563304/521799)byuserFrank:

    WhydoesJavasArea#equalsmethodnotoverrideObject#equals?

    Interestingly,thereisaArea.equals(Area)(http://docs.oracle.com/javase/8/docs/api/java/awt/geom/Area.html#equalsjava.awt.geom.Area)methodwhichreallytakesanAreaargument,insteadofaObjectargumentasdeclaredinObject.equals().Thisleadstorathernastybehaviour,asdiscoveredbyFrank:

    @org.junit.TestpublicvoidtestEquals(){java.awt.geom.Areaa=newjava.awt.geom.Area();java.awt.geom.Areab=newjava.awt.geom.Area();assertTrue(a.equals(b));//>true

    java.lang.Objecto=b;assertTrue(a.equals(o));//>false}

    Technically,itiscorrectforAWTsAreatohavebeenimplementedthisway(ashashCode()isntimplementedeither),butthewayJavaresolvesmethods,andthewayprogrammersdigestcodethathasbeenwrittenliketheabovecode,itisreallyaterribleideatooverloadtheequalsmethod.

    Nostaticequals,either

    Theserulesalsoholdtrueforstaticequals()methods,suchasforinstanceApacheCommonsLang(http://commons.apache.org/proper/commonslang/)s

    ObjectUtils.equals(Objecto1,Objecto2)

    Theconfusionherearisesbythefactthatyoucannotstaticimportthisequalsmethod:

    importstaticorg.apache.commons.lang.ObjectUtils.equals;

    Whenyounowtypethefollowing:

    equals(obj1,obj2);

    Youwillgetacompilererror:

    Themethodequals(Object)inthetypeObjectisnotapplicableforthearguments(,)

  • 3/24/2015 java|Java,SQLandjOOQ.

    http://blog.jooq.org/category/java/ 21/48

    Thereasonforthisisthatmethodsthatareinthescopeofthecurrentclassanditssupertypeswillalwaysshadowanythingthatyouimportthisway.Thefollowingdoesntworkeither:

    importstaticorg.apache.commons.lang.ObjectUtils.defaultIfNull;

    publicclassTest{voidtest(){defaultIfNull(null,null);//^^compilationerrorhere}

    voiddefaultIfNull(){}}

    DetailsinthisStackOverflowquestion(http://stackoverflow.com/q/7890853/521799).

    Conclusion

    Theconclusionissimple.neveroverloadanyofthemethodsdeclaredinObject(overridingisfine,ofcourse).Thisincludes:

    clone()equals()finalize()getClass()hashCode()notify()notifyAll()toString()wait()

    Ofcourse,itwouldbegreatifthosemethodswerentdeclaredinObjectinthefirstplace,butthatshiphassailed20yearsago.

    injava,java88Comments

    Top10EasyPerformanceOptimisationsinJava

    February5,2015

  • 3/24/2015 java|Java,SQLandjOOQ.

    http://blog.jooq.org/category/java/ 22/48

    Therehasbeenalotofhypeaboutthebuzzwordwebscale(http://www.mongodbiswebscale.com/),andpeoplearegoingthroughlengthsofreorganisingtheirapplicationarchitecturetogettheirsystemstoscale.

    Butwhatisscaling,andhowcanwemakesurethatwecanscale?

    Differentaspectsofscaling

    Thehypementionedaboveismostlyaboutscalingload,i.e.tomakesurethatasystemthatworksfor1userwillalsoworkwellfor10users,or100users,ormillions.Ideally,yoursystemisasstatelessaspossiblesuchthatthefewpiecesofstatethatreallyremaincanbetransferredandtransformedonanyprocessingunitinyournetwork.Whenloadisyourproblem,latencyisprobablynot,soitsOKifindividualrequeststake50100ms.Thisisoftenalsoreferredtoasscalingout

    Anentirelydifferentaspectofscalingisaboutscalingperformance,i.e.tomakesurethatanalgorithmthatworksfor1pieceofinformationwillalsoworkwellfor10pieces,or100pieces,ormillions.WhetherthistypeofscalingisfeasibleisbestdescribedbyBigONotation(http://en.wikipedia.org/wiki/Big_O_notation).Latencyisthekillerwhenscalingperformance.Youwanttodoeverythingpossibletokeepallcalculationonasinglemachine.Thisisoftenalsoreferredtoasscalingup

    Iftherewasanythinglikefreelunch(thereisnt(https://en.wikipedia.org/wiki/CAP_theorem)),wecouldindefinitelycombinescalingupandout.Anyway,today,weregoingtolookatsomeveryeasywaystoimprovethingsontheperformanceside.

    BigONotation

    Java7sForkJoinPool(http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ForkJoinPool.html)aswellasJava8sparallelStream(docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html)helpparallelisingstuff,whichisgreatwhenyoudeployyourJavaprogramontoamulticoreprocessormachine.Theadvantageofsuchparallelismcomparedtoscalingacrossdifferentmachinesonyournetworkisthefactthatyoucanalmostcompletelyeliminatelatencyeffects,asallcorescanaccessthesamememory.

    Butdontbefooledbytheeffectthatparallelismhas!Rememberthefollowingtwothings:

    Parallelismeatsupyourcores.Thisisgreatforbatchprocessing,butanightmareforasynchronousservers(suchasHTTP).Therearegoodreasonswhyweveusedthesinglethreadservletmodelinthepastdecades.Soparallelismonlyhelpswhenscalingup.ParallelismhasnoeffectonyouralgorithmsBigONotation.IfyouralgorithmisO(nlogn),andyouletthatalgorithmrunonccores,youwillstillhaveanO(nlogn/c)algorithm,ascisaninsignificantconstantinyouralgorithmscomplexity.Youwillsavewallclocktime,butnotreducecomplexity!

    Thebestwaytoimproveperformance,ofcourse,isbyreducingalgorithmcomplexity.ThekillerisachieveO(1)orquasiO(1),ofcourse,forinstanceaHashMaplookup.Butthatisnotalwayspossible,letaloneeasy.

    Ifyoucannotreduceyourcomplexity,youcanstillgainalotofperformanceifyoutweakyouralgorithm

  • 3/24/2015 java|Java,SQLandjOOQ.

    http://blog.jooq.org/category/java/ 23/48

    Ifyoucannotreduceyourcomplexity,youcanstillgainalotofperformanceifyoutweakyouralgorithmwhereitreallymatters,ifyoucanfindtherightspots.Assumethefollowingvisualrepresentationofanalgorithm:

    (https://lukaseder.files.wordpress.com/2015/02/algorithm2.png)

    TheoverallcomplexityofthealgorithmisO(N ),orO(NxOxP)ifwewanttodealwithindividualordersofmagnitude.However,whenprofilingthiscode,youmightfindafunnyscenario:

    Onyourdevelopmentbox,theleftbranch(N>M>Heavyoperation)istheonlybranchthatyoucanseeinyourprofiler,becausethevaluesforOandParesmallinyourdevelopmentsampledata.Onproduction,however,therightbranch(N>O>P>EasyoperationoralsoN.O.P.E.)isreallycausingtrouble.YouroperationsteammighthavefiguredthisoutusingAppDynamics(http://www.appdynamics.com),orDynaTrace(http://www.dynatrace.com),orsomesimilarsoftware.

    Withoutproductiondata,youmightquicklyjumptoconclusionsandoptimisetheheavyoperation.Youshiptoproductionandyourfixhasnoeffect.

    Therearenogoldenrulestooptimisationapartfromthefactsthat:

    AwelldesignedapplicationismucheasiertooptimisePrematureoptimisationwillnotsolveanyperformanceproblems,butmakeyourapplicationlesswelldesigned,whichinturnmakesithardertobeoptimised

    Enoughtheory.Letsassumethatyouhavefoundtherightbranchtobetheissue.Itmaywellbethataveryeasyoperationisblowingupinproduction,becauseitiscalledlotsandlotsoftimes(ifN,O,andParelarge).PleasereadthisarticleinthecontextoftherebeingaproblemattheleafnodeofaninevitableO(N )algorithm.Theseoptimisationswonthelpyouscale.Theyllhelpyousaveyourcustomersdayfornow,deferringthedifficultimprovementoftheoverallalgorithmuntillater!

    Herearethetop10easyperformanceoptimisationsinJava:

    3

    3

  • 3/24/2015 java|Java,SQLandjOOQ.

    http://blog.jooq.org/category/java/ 24/48

    1.UseStringBuilder

    ThisshouldbeyourdefaultinalmostallJavacode.Trytoavoidthe+operator.Sure,youmayarguethatitisjustsyntaxsugarforaStringBuilder(http://docs.oracle.com/javase/8/docs/api/java/lang/StringBuilder.html)anyway,asin:

    Stringx="a"+args.length+"b";

    whichcompilesto

    0newjava.lang.StringBuilder[16]3dup4ldc[18]6invokespecialjava.lang.StringBuilder(java.lang.String)[20]9aload_0[args]10arraylength11invokevirtualjava.lang.StringBuilder.append(int):java.lang.StringBuilder[23]14ldc[27]16invokevirtualjava.lang.StringBuilder.append(java.lang.String):java.lang.StringBuilder[29]19invokevirtualjava.lang.StringBuilder.toString():java.lang.String[32]22astore_1[x]

    Butwhathappens,iflateron,youneedtoamendyourStringwithoptionalparts?

    Stringx="a"+args.length+"b";

    if(args.length==1)x=x+args[0];

    YouwillnowhaveasecondStringBuilder,thatjustneedlesslyconsumesmemoryoffyourheap,puttingpressureonyourGC.Writethisinstead:

    StringBuilderx=newStringBuilder("a");x.append(args.length);x.append("b");

    if(args.length==1);x.append(args[0]);

    Takeaway

  • 3/24/2015 java|Java,SQLandjOOQ.

    http://blog.jooq.org/category/java/ 25/48

    Intheaboveexample,itisprobablycompletelyirrelevantifyoureusingexplicitStringBuilderinstances,orifyourelyontheJavacompilercreatingimplicitinstancesforyou.Butremember,wereintheN.O.P.E.branch.EveryCPUcyclethatwerewastingonsomethingasstupidasGCorallocatingaStringBuildersdefaultcapacity,werewastingNxOxPtimes.

    Asaruleofthumb,alwaysuseaStringBuilder(http://docs.oracle.com/javase/8/docs/api/java/lang/StringBuilder.html)ratherthanthe+operator.Andifyoucan,keeptheStringBuilderreferenceacrossseveralmethods,ifyourStringismorecomplextobuild.ThisiswhatjOOQ(http://www.jooq.org)doeswhenyougenerateacomplexSQLstatement.ThereisonlyoneStringBuilderthattraversesyourwholeSQLAST(AbstractSyntaxTree)(http://en.wikipedia.org/wiki/Abstract_syntax_tree)

    Andforcryingoutloud,ifyoustillhaveStringBuffer(http://docs.oracle.com/javase/8/docs/api/java/lang/StringBuffer.html)references,doreplacethembyStringBuilder.Youreallyhardlyeverneedtosynchronizeonastringbeingcreated.

    2.Avoidregularexpressions

    Regularexpressionsarerelativelycheapandconvenient.ButifyoureintheN.O.P.E.branch,theyreabouttheworstthingyoucando.Ifyouabsolutelymustuseregularexpressionsincomputationintensivecodesections,atleastcachethePattern(http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html)referenceinsteadofcompilingitafreshallthetime:

    staticfinalPatternHEAVY_REGEX=Pattern.compile("(((X)*Y)*Z)*");

    Butifyourregularexpressionisreallysillylike

    String[]parts=ipAddress.split("\\.");

    thenyoureallybetterresorttoordinarychar[]orindexbasedmanipulation.Forexamplethisutterlyunreadableloopdoesthesamething:

  • 3/24/2015 java|Java,SQLandjOOQ.

    http://blog.jooq.org/category/java/ 26/48

    intlength=ipAddress.length();intoffset=0;intpart=0;for(inti=0;i

  • 3/24/2015 java|Java,SQLandjOOQ.

    http://blog.jooq.org/category/java/ 27/48

    privateclassItrimplementsIterator{intcursor;intlastRet=1;intexpectedModCount=modCount;//...

    Instead,youcanwritethefollowing,equivalentloopandwasteonlyasingleintvalueonthestack,whichisdirtcheap:

    intsize=strings.size();for(inti=0;i

  • 3/24/2015 java|Java,SQLandjOOQ.

    http://blog.jooq.org/category/java/ 28/48

    if(type==Integer.class){result=(T)wasNull(rs,Integer.valueOf(rs.getInt(index)));}

    //Andthen...staticfinalTwasNull(ResultSetrs,Tvalue)throwsSQLException{returnrs.wasNull()?null:value;}

    ThislogicwillnowcallResultSet.wasNull()everytimeyougetanintfromtheresultset.ButthegetInt()contractreads:

    Returns:thecolumnvalue;ifthevalueisSQLNULL,thevaluereturnedis0

    Thus,asimple,yetpossiblydrasticimprovementtotheabovewouldbe:

    staticfinalTwasNull(ResultSetrs,Tvalue)throwsSQLException{return(value==null||(value.intValue()==0&&rs.wasNull()))?null:value;}

    So,thisisanobrainer:

    Takeaway

    Dontcallexpensivemethodsinanalgorithmsleafnodes,butcachethecallinstead,oravoiditifthemethodcontractallowsit.

    5.Useprimitivesandthestack

    TheaboveexampleisfromjOOQ(http://www.jooq.org),whichusesalotofgenerics,andthusisforcedtousewrappertypesforbyte,short,int,andlongatleastbeforegenericswillbespecialisableinJava10andprojectValhalla(http://cr.openjdk.java.net/~briangoetz/valhalla/specialization.html).Butyoumaynothavethisconstraintinyourcode,soyoushouldtakeallmeasurestoreplace:

    //GoestotheheapIntegeri=817598;

  • 3/24/2015 java|Java,SQLandjOOQ.

    http://blog.jooq.org/category/java/ 29/48

    bythis:

    //Staysonthestackinti=817598;

    Thingsgetworsewhenyoureusingarrays:

    //Threeheapobjects!Integer[]i={1337,424242};

    bythis:

    //Oneheapobject.int[]i={1337,424242};

    Takeaway

    WhenyouredeepdowninyourN.O.P.E.branch,youshouldbeextremelywaryofusingwrappertypes.ChancesarethatyouwillcreatealotofpressureonyourGC,whichhastokickinallthetimetocleanupyourmess.

    Aparticularlyusefuloptimisationmightbetousesomeprimitivetypeandcreatelarge,onedimensionalarraysofit,andacoupleofdelimitervariablestoindicatewhereexactlyyourencodedobjectislocatedonthearray.

    Anexcellentlibraryforprimitivecollections,whichareabitmoresophisticatedthanyouraverageint[]istrove4j(http://trove4j.sourceforge.net),whichshipswithLGPL.

    Exception

    Thereisanexceptiontothisrule:booleanandbytehavefewenoughvaluestobecachedentirelybytheJDK.Youcanwrite:

    Booleana1=true;//...syntaxsugarfor:Booleana2=Boolean.valueOf(true);

    Byteb1=(byte)123;//...syntaxsugarfor:Byteb2=Byte.valueOf((byte)123);

    Thesameistrueforlowvaluesoftheotherintegerprimitivetypes,includingchar,short,int,long.

    Butonlyifyoureautoboxingthem,orcallingTheType.valueOf(),notwhenyoucalltheconstructor!

    Nevercalltheconstructoronwrappertypes,unlessyoureallywantanewinstance

    Thisfactcanalsohelpyouwriteasophisticated,trollingAprilFoolsjokeforyourcoworkers(http://blog.jooq.org/2013/10/17/addsomeentropytoyourjvm/)

  • 3/24/2015 java|Java,SQLandjOOQ.

    http://blog.jooq.org/category/java/ 30/48

    Offheap

    Ofcourse,youmightalsowanttoexperimentwithoffheaplibraries,althoughtheyremoreofastrategicdecision,notalocaloptimisation.

    AninterestingarticleonthatsubjectbyPeterLawreyandBenCottonis:OpenJDKandHashMapSafelyTeachinganOldDogNew(OffHeap!)Tricks(http://www.infoq.com/articles/OpenJDKandHashMapOffHeap)

    6.Avoidrecursion

    ModernfunctionalprogramminglanguageslikeScalaencouragetheuseofrecursion,astheyoffermeansofoptimisingtailrecursingalgorithmsbackintoiterativeones(http://stackoverflow.com/q/33923/521799).Ifyourlanguagesupportssuchoptimisations,youmightbefine.Buteventhen,theslightestchangeofalgorithmmightproduceabranchthatpreventsyourrecursionfrombeingtailrecursive.Hopefullythecompilerwilldetectthis!Otherwise,youmightbewastingalotofstackframesforsomethingthatmighthavebeenimplementedusingonlyafewlocalvariables.

    Takeaway

    Theresnotmuchtosayaboutthisapartfrom:AlwayspreferiterationoverrecursionwhenyouredeepdowntheN.O.P.E.branch

    7.UseentrySet()

    WhenyouwanttoiteratethroughaMap(https://docs.oracle.com/javase/8/docs/api/java/util/Map.html),andyouneedbothkeysandvalues,youmusthaveaverygoodreasontowritethefollowing:

    for(Kkey:map.keySet()){Vvalue:map.get(key);}

    ratherthanthefollowing:

    for(Entryentry:map.entrySet()){Kkey=entry.getKey();Vvalue=entry.getValue();}

    WhenyoureintheN.O.P.E.branch,youshouldbewaryofmapsanyway,becauselotsandlotsofO(1)map

  • 3/24/2015 java|Java,SQLandjOOQ.

    http://blog.jooq.org/category/java/ 31/48

    WhenyoureintheN.O.P.E.branch,youshouldbewaryofmapsanyway,becauselotsandlotsofO(1)mapaccessoperationsarestilllotsofoperations.Andtheaccessisntfreeeither.Butatleast,ifyoucannotdowithoutmaps,useentrySet()(https://docs.oracle.com/javase/8/docs/api/java/util/Map.html#entrySet)toiteratethem!TheMap.Entryinstanceisthereanyway,youonlyneedtoaccessit.

    Takeaway

    AlwaysuseentrySet()whenyouneedbothkeysandvaluesduringmapiteration.

    8.UseEnumSetorEnumMap

    Therearesomecaseswherethenumberofpossiblekeysinamapisknowninadvanceforinstancewhenusingaconfigurationmap.Ifthatnumberisrelativelysmall,youshouldreallyconsiderusingEnumSetorEnumMap,insteadofregularHashSetorHashMapinstead.ThisiseasilyexplainedbylookingatEnumMap.put():

    privatetransientObject[]vals;

    publicVput(Kkey,Vvalue){//...intindex=key.ordinal();vals[index]=maskNull(value);//...}

    Theessenceofthisimplementationisthefactthatwehaveanarrayofindexedvaluesratherthanahashtable.Wheninsertinganewvalue,allwehavetodotolookupthemapentryisasktheenumforitsconstantordinal,whichisgeneratedbytheJavacompileroneachenumtype.Ifthisisaglobalconfigurationmap(i.e.onlyoneinstance),theincreasedaccessspeedwillhelpEnumMapheavilyoutperformHashMap,whichmayuseabitlessheapmemory,butwhichwillhavetorunhashCode()andequals()oneachkey.

    Takeaway

    EnumandEnumMapareveryclosefriends.Wheneveryouuseenumlikestructuresaskeys,consideractuallymakingthosestructuresenumsandusingthemaskeysinEnumMap.

    9.OptimiseyourhashCode()andequals()methods

    IfyoucannotuseanEnumMap,atleastoptimiseyourhashCode()andequals()methods.AgoodhashCode()methodisessentialbecauseitwillpreventfurthercallstothemuchmoreexpensiveequals()asitwillproducemoredistincthashbucketspersetofinstances.

  • 3/24/2015 java|Java,SQLandjOOQ.

    http://blog.jooq.org/category/java/ 32/48

    Ineveryclasshierarchy,youmayhavepopularandsimpleobjects.LetshavealookatjOOQsorg.jooq.Table(http://www.jooq.org/javadoc/latest/org/jooq/Table.html)implementations.

    ThesimplestandfastestpossibleimplementationofhashCode()isthisone:

    //AbstractTable,acommonTablebaseimplementation:

    @OverridepublicinthashCode(){

    //[#1938]ThisisamuchmoreefficienthashCode()//implementationcomparedtothatofstandard//QueryPartsreturnname.hashCode();}

    wherenameissimplythetablename.Wedontevenconsidertheschemaoranyotherpropertyofthetable,asthetablenamesareusuallydistinctenoughacrossadatabase.Also,thenameisastring,soithasalreadyacachedhashCode()valueinside.

    Thecommentisimportant,becauseAbstractTableextendsAbstractQueryPart,whichisacommonbaseimplementationforanyAST(AbstractSyntaxTree)(https://en.wikipedia.org/wiki/Abstract_syntax_tree)element.ThecommonASTelementdoesnothaveanyproperties,soitcannotmakeanyassumptionsanoptimisedhashCode()implementation.Thus,theoverriddenmethodlookslikethis:

    //AbstractQueryPart,acommonASTelement//baseimplementation:

    @OverridepublicinthashCode(){//Thisisaworkingdefaultimplementation.//Itshouldbeoverriddenbyconcretesubclasses,//toimproveperformancereturncreate().renderInlined(this).hashCode();}

    Inotherwords,thewholeSQLrenderingworkflowhastobetriggeredtocalculatethehashcodeofacommonASTelement.

    Thingsgetmoreinterestingwithequals()

  • 3/24/2015 java|Java,SQLandjOOQ.

    http://blog.jooq.org/category/java/ 33/48

    //AbstractTable,acommonTablebaseimplementation:

    @Overridepublicbooleanequals(Objectthat){if(this==that){returntrue;}

    //[#2144]Nonequalitycanbedecidedearly,//withoutexecutingtheratherexpensive//implementationofAbstractQueryPart.equals()if(thatinstanceofAbstractTable){if(StringUtils.equals(name,(((AbstractTable)that).name))){returnsuper.equals(that);}

    returnfalse;}

    returnfalse;}

    Firstthing:Always(notonlyinaN.O.P.E.branch)aborteveryequals()methodearly,if:

    this==argumentthis"incompatibletype"argument

    Notethatthelatterconditionincludesargument==null,ifyoureusinginstanceoftocheckforcompatibletypes.Wevebloggedaboutthisbeforein10SubtleBestPracticeswhenCodingJava(http://blog.jooq.org/2013/08/20/10subtlebestpracticeswhencodingjava/).

    Now,afterabortingcomparisonearlyinobviouscases,youmightalsowanttoabortcomparisonearlywhenyoucanmakepartialdecisions.Forinstance,thecontractofjOOQsTable.equals()isthatfortwotablestobeconsideredequal,theymustbeofthesamename,regardlessoftheconcreteimplementationtype.Forinstance,thereisnowaythesetwoitemscanbeequal:

    com.example.generated.Tables.MY_TABLEDSL.tableByName("MY_OTHER_TABLE")

    Iftheargumentcannotbeequaltothis,andifwecancheckthateasily,letsdosoandabortifthecheckfails.Ifthechecksucceeds,wecanstillproceedwiththemoreexpensiveimplementationfromsuper.Giventhatmostobjectsintheuniversearenotequal,weregoingtosavealotofCPUtimebyshortcuttingthismethod.

    someobjectsaremoreequalthanothers

    InthecaseofjOOQ,mostinstancesarereallytablesasgeneratedbythejOOQsourcecodegenerator(http://www.jooq.org/doc/3.5/manual/codegeneration/),whoseequals()implementationisevenfurtheroptimised.Thedozensofothertabletypes(derivedtables,tablevaluedfunctions,arraytables,joinedtables,

  • 3/24/2015 java|Java,SQLandjOOQ.

    http://blog.jooq.org/category/java/ 34/48

    pivottables,commontableexpressions,etc.)cankeeptheirsimpleimplementation.

    10.Thinkinsets,notinindividualelements

    Lastbutnotleast,thereisathingthatisnotJavarelatedbutappliestoanylanguage.Besides,wereleavingtheN.O.P.E.branchasthisadvicemightjusthelpyoumovefromO(N )toO(nlogn),orsomethinglikethat.

    Unfortunately,manyprogrammersthinkintermsofsimple,localalgorithms.Theyresolvingaproblemstepbystep,branchbybranch,loopbyloop,methodbymethod.Thatstheimperativeand/orfunctionalprogrammingstyle.Whileitisincreasinglyeasytomodelthebiggerpicturewhengoingfrompureimperativetoobjectoriented(stillimperative)tofunctionalprogramming,allthesestyleslacksomethingthatonlySQLandRandsimilarlanguageshave:

    Declarativeprogramming.

    InSQL(andweloveit,asthisisthejOOQblog(http://blog.jooq.org))youcandeclaretheoutcomeyouwanttogetfromyourdatabase,withoutmakinganyalgorithmicimplicationswhatsoever.Thedatabasecanthentakeallthemetadataavailableintoconsideration(e.g.constraints,keys,indexes,etc.(http://blog.jooq.org/2011/11/25/howschemametadataimpactsoraclequerytransformations/))tofigureoutthebestpossiblealgorithm.

    Intheory,thishasbeenthemainideabehindSQLandrelationalcalculus(https://en.wikipedia.org/wiki/Relational_calculus)fromthebeginning.Inpractice,SQLvendorshaveimplementedhighlyefficientCBOs(CostBasedOptimisers)(https://www.youtube.com/watch?v=CjY8TCU69TU)onlysincethelastdecade,sostaywithusinthe2010swhenSQLwillfinallyunleashitsfullpotential(itwasabouttime!)

    ButyoudonthavetodoSQLtothinkinsets.Sets/collections/bags/listsareavailableinalllanguagesandlibraries.Themainadvantageofusingsetsisthefactthatyouralgorithmswillbecomemuchmuchmoreconcise.Itissomucheasiertowrite:

    SomeSetINTERSECTSomeOtherSet

    ratherthan:

    //PreJava8Setresult=newHashSet();for(Objectcandidate:someSet)if(someOtherSet.contains(candidate))result.add(candidate);

    //EvenJava8doesn'treallyhelpsomeSet.stream().filter(someOtherSet::contains).collect(Collectors.toSet());

    3

  • 3/24/2015 java|Java,SQLandjOOQ.

    http://blog.jooq.org/category/java/ 35/48

    SomemayarguethatfunctionalprogrammingandJava8willhelpyouwriteeasier,moreconcisealgorithms.Thatsnotnecessarilytrue.YoucantranslateyourimperativeJava7loopintoafunctionalJava8Streamcollection,butyourestillwritingtheverysamealgorithm.WritingaSQLesqueexpressionisdifferent.This

    SomeSetINTERSECTSomeOtherSet

    canbeimplementedin1000waysbytheimplementationengine.Aswevelearnedtoday,perhapsitiswisetotransformthetwosetsintoEnumSetautomatically,beforerunningtheINTERSECToperation.PerhapswecanparallelisethisINTERSECTwithoutmakinglowlevelcallstoStream.parallel()(https://docs.oracle.com/javase/8/docs/api/java/util/stream/BaseStream.html#parallel)

    Conclusion

    Inthisarticle,wevetalkedaboutoptimisationsdoneontheN.O.P.E.branch,i.e.deepdowninahighcomplexityalgorithm.Inourcase,beingthejOOQ(http://www.jooq.org)developers,wehaveinterestinoptimisingourSQLgeneration:

    EveryqueryisgeneratedonlyonasingleStringBuilderOurtemplatingengineactuallyparsescharacters,insteadofusingregularexpressionsWeusearrayswhereverwecan,especiallywheniteratingoverlistenersWestayclearofJDBCmethodsthatwedonthavetocalletc

    jOOQisatthebottomofthefoodchain,becauseitsthe(second)lastAPIthatisbeingcalledbyourcustomersapplicationsbeforethecallleavestheJVMtoentertheDBMS.BeingatthebottomofthefoodchainmeansthateverylineofcodethatisexecutedinjOOQmightbecalledNxOxPtimes,sowemustoptimiseeagerly.

    YourbusinesslogicisnotdeepdownintheN.O.P.E.branch.Butyourown,homegrowninfrastructurelogicmaybe(customSQLframeworks,customlibraries,etc.)Thoseshouldbereviewedaccordingtotherulesthatweveseentoday.Forinstance,usingJavaMissionControl(http://blog.jooq.org/2014/02/17/freejavaprofilingwithoraclejavamissioncontrol/)oranyotherprofiler.

    Likedthisarticle?

    Ifyoucantgoandprofileyourapplicationrightnow,youmightenjoyreadinganyofthesearticlesinstead:

    10SubtleMistakesWhenUsingtheStreamsAPI(http://blog.jooq.org/2014/06/13/java8friday10subtlemistakeswhenusingthestreamsapi/)10ThingsYouDidntKnowAboutJava(http://blog.jooq.org/2014/11/03/10thingsyoudidntknowaboutjava/)10SubtleBestPracticeswhenCodingJava(http://blog.jooq.org/2013/08/20/10subtlebestpracticeswhencodingjava/)

    injavaFebruary2,2015

  • 3/24/2015 java|Java,SQLandjOOQ.

    http://blog.jooq.org/category/java/ 36/48

    4Comments

    Top5UseCasesForNestedTypes

    Therehasbeenaninterestingdiscussiononreddit,theotherdayStaticInnerClasses.Whenisittoomuch?(http://redd.it/2u4512)

    First,letsreviewalittlebitofbasichistoricJavaknowledge.Javathelanguageoffersfourlevelsofnestingclasses(http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html),andbyJavathelanguage,Imeanthattheseconstructsaremeresyntaxsugar.TheydontexistintheJVM,whichonlyknowsordinaryclasses.

    (Static)Nestedclasses

    classOuter{staticclassInner{}}

    Inthiscase,InneriscompletelyindependentofOuter,exceptforacommon,sharednamespace.

    Innerclasses

    classOuter{classInner{}}

    Inthiscase,InnerinstanceshaveanimplicitreferencetotheirenclosingOuterinstance.Inotherwords,therecanbenoInnerinstancewithoutanassociatedOuterinstance.

    TheJavawayofcreatingsuchaninstanceisthis:

    Outer.Inneryikes=newOuter().newInner();

    Whatlookstotallyawkwardmakesalotofsense.ThinkaboutcreatinganInnerinstancesomewhereinsideofOuter:

  • 3/24/2015 java|Java,SQLandjOOQ.

    http://blog.jooq.org/category/java/ 37/48

    classOuter{classInner{}

    voidsomewhereInside(){//We'realreadyinthescopeofOuter.//Wedon'thavetoqualifyInnerexplicitly.InneraaahOK;

    //Thisiswhatwe'reusedtowriting.aaahOK=newInner();

    //Asallotherlocallyscopedmethods,wecan//accesstheInnerconstructorby//dereferencingitfrom"this".Wejust//hardlyeverwrite"this"aaahOK=this.newInner();}}

    Notethatmuchlikethepublicorabstractkeywords,thestatickeywordisimplicitfornestedinterfaces.Whilethefollowinghypotheticalsyntaxmightlookfamiliaratfirstsight:

    classOuter{interfaceInner{defaultvoiddoSomething(){Outer.this.doSomething();}}

    voiddoSomething(){}}

    itisnotpossibletowritetheabove.Apartfromthelackofakeyword,theredontseemtobeanyobviousreasonwhyinnerinterfacesshouldntbepossible.Idsuspecttheusualtheremustbesomereallyedgecaseycaveatrelatedtobackwardscompatibilityand/ormultipleinheritancethatpreventsthis.

    Localclasses

    classOuter{voidsomewhereInside(){classInner{}}}

  • 3/24/2015 java|Java,SQLandjOOQ.

    http://blog.jooq.org/category/java/ 38/48

    LocalclassesareprobablyoneoftheleastknownfeaturesinJava,asthereishardlyanyuseforthem.Localclassesarenamedtypeswhosescopeextendsonlytotheenclosingmethod.Obvioususecasesarewhenyouwanttoreusesuchatypeseveraltimeswithinthatmethod,e.g.toconstructseveralsimilarlistenersinaJavaFXapplication.

    Anonymousclasses

    classOuter{Serializabledummy=newSerializable(){};}

    Anonymousclassesaresubtypesofanothertypewithonlyonesingleinstance.

    Top5UseCasesForNestedClasses

    Allofanonymous,local,andinnerclasseskeepareferencetotheirenclosinginstance,iftheyrenotdefinedinastaticcontext.Thismaycausealotoftroubleifyouletinstancesoftheseclassesleakoutsideoftheirscope.Readmoreaboutthattroubleinourarticle:DontbeClever:TheDoubleCurlyBracesAntiPattern(http://blog.jooq.org/2014/12/08/dontbecleverthedoublecurlybracesantipattern/).

    Often,however,youdowanttoprofitfromthatenclosinginstance.Itcanbequiteusefultohavesomesortofmessageobjectthatyoucanreturnwithoutdisclosingtheactualimplementation:

    classOuter{

    //Thisimplementationisprivate...privateclassInnerimplementsMessage{@OverridepublicvoidgetMessage(){Outer.this.someoneCalledMe();}}

    //...butwecanreturnit,beingof//typeMessageMessagehello(){returnnewInner();}

    voidsomeoneCalledMe(){}}

    With(static)nestedclasses,however,thereisnoenclosingscopeastheInnerinstanceiscompletelyindependentofanyOuterinstance.Sowhatsthepointofusingsuchanestedclass,ratherthanatopleveltype?

  • 3/24/2015 java|Java,SQLandjOOQ.

    http://blog.jooq.org/category/java/ 39/48

    1.Associationwiththeoutertype

    Ifyouwanttocommunicatetothewholeworld,hey,this(inner)typeistotallyrelatedtothis(outer)type,anddoesntmakesenseonitsown,thenyoucannestthetypes.ThishasbeendonewithMapandMap.Entry,forinstance:

    publicinterfaceMap{interfaceEntry{}}

    2.Hidingfromtheoutsideoftheoutertype

    Ifpackage(default)visibilityisntenoughforyourtypesyoucancreateprivatestaticclassesthatareavailableonlytotheirenclosingtypeandtoallothernestedtypesoftheenclosingtype.Thisisreallythemainusecaseforstaticnestedclasses.

    classOuter{privatestaticclassInner{}}

    classOuter2{Outer.Innernope;}

    3.Protectedtypes

    Thisisreallyaveryrareusecase,butsometimes,withinaclasshierarchy,youneedtypesthatyouwanttomakeavailableonlytosubtypesofagiventype.Thisisausecaseforprotectedstaticclasses:

  • 3/24/2015 java|Java,SQLandjOOQ.

    http://blog.jooq.org/category/java/ 40/48

    classParent{protectedstaticclassOnlySubtypesCanSeeMe{}

    protectedOnlySubtypesCanSeeMesomeMethod(){returnnewOnlySubtypesCanSeeMe();}}

    classChildextendsParent{OnlySubtypesCanSeeMewow=someMethod();}

    4.Toemulatemodules

    UnlikeCeylon,Javadoesnthavefirstclassmodules(http://blog.jooq.org/2013/12/03/top10ceylonlanguagefeaturesiwishwehadinjava/).WithMavenorOSGi,itispossibletoaddsomemodularbehaviourtoJavasbuild(Maven)orruntime(OSGi)environments,butifyouwanttoexpressmodulesincode,thisisntreallypossible.

    However,youcanestablishmodulesbyconventionbyusingstaticnestedclasses.Letslookatthejava.util.stream(http://docs.oracle.com/javase/8/docs/api/java/util/stream/packagesummary.html)package.Wecouldconsideritamodule,andwithinthismodule,wehaveacoupleofsubmodules,orgroupsoftypes,suchastheinternaljava.util.stream.Nodesclass,whichroughlylookslikethis:

    finalclassNodes{privateNodes(){}privatestaticabstractclassAbstractConcNode{}staticfinalclassConcNode{staticfinalclassOfInt{}staticfinalclassOfLong{}}privatestaticfinalclassFixedNodeBuilder{}//...}

    SomeofthisNodesstuffisavailabletoallofthejava.util.streampackage,sowemightsaythatthewaythisiswritten,wehavesomethinglike:

    asyntheticjava.util.stream.nodessubpackage,visibleonlytothejava.util.streammoduleacoupleofjava.util.stream.nodes.*types,visiblealsoonlytothejava.util.streammoduleacoupleoftoplevelfunctions(staticmethods)inthesyntheticjava.util.stream.nodespackage

  • 3/24/2015 java|Java,SQLandjOOQ.

    http://blog.jooq.org/category/java/ 41/48

    LooksalotlikeCeylon,tome!(http://blog.jooq.org/2013/12/03/top10ceylonlanguagefeaturesiwishwehadinjava/)

    5.Cosmeticreasons

    Thelastbitisratherboring.Orsomemayfinditinteresting(http://blog.jooq.org/2014/07/25/top10veryveryveryimportanttopicstodiscuss/).Itsabouttaste,oreaseofwritingthings.Someclassesarejustsosmallandunimportant,itsjusteasiertowritetheminsideofanotherclass.Savesyoua.javafile.Whynot.

    Conclusion

    IntimesofJava8,thinkingabouttheveryoldfeaturesofJavathelanguagemightnotprovetobeextremelyexciting.Staticnestedclassesareawellunderstoodtoolforacoupleofnicheusecases.

    Thetakeawayfromthisarticle,however,isthis.Everytimeyounestaclass,besuretomakeitstaticifyoudontabsolutelyneedareferencetotheenclosinginstance.Youneverknowwhenthatreferenceisblowingupyourapplicationinproduction(http://blog.jooq.org/2014/12/08/dontbecleverthedoublecurlybracesantipattern/).

    injava,java84Comments

    YouWillRegretApplyingOverloadingwithLambdas!

    WritinggoodAPIsishard.Extremelyhard.YouhavetothinkofanincredibleamountofthingsifyouwantyouruserstoloveyourAPI.Youhavetofindtherightbalancebetween:

    1. Usefulness2. Usability3. Backwardcompatibility4. Forwardcompatibility

    Wevebloggedaboutthistopicbefore,inourarticle:HowtoDesignaGood,RegularAPI(http://blog.jooq.org/2013/03/30/howtodesignagoodregularapi/).Today,weregoingtolookintohow

    January29,2015

  • 3/24/2015 java|Java,SQLandjOOQ.

    http://blog.jooq.org/category/java/ 42/48

    Java8changestherules

    Yes!

    Overloadingisanicetooltoprovidecovenienceintwodimensions:

    ByprovidingargumenttypealternativesByprovidingargumentdefaultvalues

    ExamplesfortheabovefromtheJDKinclude:

    publicclassArrays{

    //Argumenttypealternativespublicstaticvoidsort(int[]a){...}publicstaticvoidsort(long[]a){...}

    //ArgumentdefaultvaluespublicstaticIntStreamstream(int[]array){...}publicstaticIntStreamstream(int[]array,intstartInclusive,intendExclusive){...}}

    ThejOOQAPIisobviouslyfullofsuchconvenience.AsjOOQisaDSLforSQL(http://www.jooq.org),we

  • 3/24/2015 java|Java,SQLandjOOQ.

    http://blog.jooq.org/category/java/ 43/48

    ThejOOQAPIisobviouslyfullofsuchconvenience.AsjOOQisaDSLforSQL(http://www.jooq.org),wemightevenabusealittlebit:

    publicinterfaceDSLContext{SelectSelectStepselect(SelectFieldfield1);

    SelectSelectStepselect(SelectFieldfield1,SelectFieldfield2);

    SelectSelectStepsselect(SelectFieldfield1,SelectFieldfield2,SelectFieldfield3);

    SelectSelectStepselect(SelectFieldfield1,SelectFieldfield2,SelectFieldfield3,SelectFieldfield4);

    //andsoon...}

    LanguageslikeCeylontakethisideaofconvenienceonestepfurtherbyclaimingthattheaboveistheonlyreasonablereasonwhyoverloadingisbeusedinJava.Andthus,thecreatorsofCeylonhavecompletelyremovedoverloadingfromtheirlanguage,replacingtheabovebyuniontypesandactualdefaultvaluesforarguments.E.g.

    //Uniontypesvoidsort(int[]|long[]a){...}

    //DefaultargumentvaluesIntStreamstream(int[]array,intstartInclusive=0,intendInclusive=array.length){...}

    ReadTop10CeylonLanguageFeaturesIWishWeHadInJava(http://blog.jooq.org/2013/12/03/top10ceylonlanguagefeaturesiwishwehadinjava/)formoreinformationaboutCeylon.

    InJava,unfortunately,wecannotuseuniontypesorargumentdefaultvalues.SowehavetouseoverloadingtoprovideourAPIconsumerswithconveniencemethods.

    Ifyourmethodargumentisafunctionalinterface(http://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html),however,thingschangeddrasticallybetweenJava7andJava8,withrespecttomethodoverloading.AnexampleisgivenherefromJavaFX.

  • 3/24/2015 java|Java,SQLandjOOQ.

    http://blog.jooq.org/category/java/ 44/48

    JavaFXsunfriendlyObservableList

    JavaFXenhancestheJDKcollectiontypesbymakingthemobservable.NottobeconfusedwithObservable(http://docs.oracle.com/javase/8/docs/api/java/util/Observable.html),adinosaurtypefromtheJDK1.0andfrompreSwingdays.

    JavaFXsownObservable(http://docs.oracle.com/javafx/2/api/javafx/beans/Observable.html)essentiallylookslikethis:

    publicinterfaceObservable{voidaddListener(InvalidationListenerlistener);voidremoveListener(InvalidationListenerlistener);}

    Andluckily,thisInvalidationListener(http://docs.oracle.com/javafx/2/api/javafx/beans/InvalidationListener.html)isafunctionalinterface:

    @FunctionalInterfacepublicinterfaceInvalidationListener{voidinvalidated(Observableobservable);}

    Thisisgreat,becausewecandothingslike:

    Observableawesome=FXCollections.observableArrayList();awesome.addListener(fantastic>splendid.cheer());

    (noticehowIvereplacedfoo/bar/bazwithmorecheerfulterms.Weshouldalldothat.Fooandbarareso1970(http://en.wikipedia.org/wiki/Foobar))

    Unfortunately,thingsgetmorehairywhenwedowhatwewouldprobablydo,instead.I.e.insteadofdeclaringanObservable,wedlikethattobeamuchmoreusefulObservableList(http://docs.oracle.com/javafx/2/api/javafx/collections/ObservableList.html):

    ObservableListawesome=FXCollections.observableArrayList();awesome.addListener(fantastic>splendid.cheer());

    Butnow,wegetacompilationerroronthesecondline:

  • 3/24/2015 java|Java,SQLandjOOQ.

    http://blog.jooq.org/category/java/ 45/48

    awesome.addListener(fantastic>splendid.cheer());//^^^^^^^^^^^//ThemethodaddListener(ListChangeListener

  • 3/24/2015 java|Java,SQLandjOOQ.

    http://blog.jooq.org/category/java/ 46/48

    Allofthesemeasureswillremoveambiguity.Butfrankly,lambdasareonlyhalfascoolifyouhavetoexplicitlytypethelambda,ortheargumenttypes.WehavemodernIDEsthatcanperformautocompletionandhelpinfertypesjustasmuchasthecompileritself.

    ImagineifwereallywantedtocalltheotheraddListener()method,theonethattakesaListChangeListener.Wedhavetowriteanyof

    ObservableListawesome=FXCollections.observableArrayList();

    //Agh.Rememberthatwehavetorepeat"String"hereListChangeListenerhearYe=fantastic>splendid.cheer();awesome.addListener(hearYe);

    Or

    ObservableListawesome=FXCollections.observableArrayList();

    //Agh.Rememberthatwehavetorepeat"String"hereawesome.addListener((ListChangeListener)fantastic>splendid.cheer());

    Oreven

    ObservableListawesome=FXCollections.observableArrayList();

    //WTF..."extends"String??Butthat'swhatthisthingneeds...awesome.addListener((Change

  • 3/24/2015 java|Java,SQLandjOOQ.

    http://blog.jooq.org/category/java/ 47/48

    takethesamenumberofmethodarguments(asinourpreviousaddListener()example)?

    Zero.

    Thereareoverloadswhereoverloadargumentnumbersdiffer.Forinstance:

    Rcollect(Suppliersupplier,BiConsumeraccumulator,BiConsumercombiner);

    Rcollect(Collector

  • 3/24/2015 java|Java,SQLandjOOQ.

    http://blog.jooq.org/category/java/ 48/48

    BuildawebsitewithWordPress.com


Recommended