Java _ 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

description

about java, sql, and jooq

Transcript of Java _ Java, SQL and JOOQ

  • 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