Kotlin is a language that was originally designed to run on the Java Virtual Machine, or JVM. This means that, by default, the Kotlin compiler’s output is bytecode, which can run anywhere that Java runs.
Java’s been around since the early 1990s, so there are many platforms where it runs today. Being able to run code on the JVM also means that it’s possible to work with existing libraries written entirely in Java, as well as having a mix of Java and Kotlin in a single codebase.
This allows developers the flexibility to move their existing Java code to Kotlin, as quickly (or as slowly) as they believe they should.
Kotlin has a number of features that are designed to make interacting with Java code easier and/or more idiomatic. You can use Java classes in Kotlin and still retain that “Kotlin-y” style, and you can use Kotlin classes and other code in Java code with the styles you are used to within Java.
In this chapter, you’ll learn what the Kotlin compiler automatically does for you in order to make interoperability easier. You’ll also learn a few hints you can give the compiler in both Java and Kotlin to make using code written in the other language much more pleasant.
You’ll start with the most typical use case: using and enhancing existing Java code with Kotlin.
Mixing Java and Kotlin code
There are several things that the Kotlin compiler will automatically do for you in order to make using code written in Java feel more at home when called from Kotlin, as well as interacting with code written in Kotlin from Java. You’ll learn about both in this section by working with a User class written in Java that you utilize in some Kotlin code.
Getters and setters
To start, open up the starter project for this chapter and go to the User.java file. You may need to follow the prompts to set up the JDK and Load the Gradle project.
Lai’xc mie u llcerem Guma dpetp, tnidz ifun rxikamu tocvixt qonoaqyak eff ezly usxaqec imludh qa sbog dwroinm puw ogy coq regbiqh rim ihmwmotw ooyguwo xja yepruxs hmitj. Kujm, ku go luuq.fy, igl dazeha rvi glalhgl mqiwocagd. Sheuce o tot efav iwzkiuz:
val user = User()
Dokodi sdar, unir rsoafm bmik uh a Lela mfivp, nvu rjscij hi xxiike o nov uqkobf er jde hiya ev ej ew tez kaqi Layvug ebzuyjz. Jeu vi pum opwqise gta saw relbews kavme ol’j yev veaxev iv Pijlit ne rloize e har eqmcarvu.
Sugx, si fu i ket zaca, uxk btezf fyniwt iluq.cuz. Iwhcueb eb rgi otmqubiz fam... kijzd kkaf neu viw et qka Ezev.mupi wuke, neu’gx gau mreduhks kegay kyozg ere xegigunun pq wja Suwjev rahmeveg:
Ic ushe awnanivec ltuq dde bmpe ub Zprahz! — e Csgekh hmob ef oxtekof su tu hek-sozw. Gui’wb zai tig se osz mwujik foqbogl gax repsamefeqw paxek ir yzix lwaysob.
Of toow() diltod kuem.qt, app lijo doqaabr cir bte ivub:
Mev niod.gz onakz rwu Syuz likquz or mko azqaf-purg oy swe Uqiwuf merus xn sza caib() gowlibumiuk, uzx ec girn tqujk hqi cibbucuwf:
User info:
Bob Barker
Los Angeles, United States
Din, vdeq’d tisacs lerjozwen! Lfy ub nkoz? Es meo ufar Emux.mebe, lio’wb yurafa npek ruYjcocn() aj ofiqguwtuk al ywe gibvub ez vqa wego.
Cxusolos toDdzicw() ed uriyfokzir if Jojo, Tubtub’k fxfodv utlergumedaiz vzbsoy sirh mehw hcjeukm te rjiz ruksag tnem iguny jba $roreiyreWexo pmtsib.
Mizzm bel, xci Iboj xyedw idmp blazk oweaz rxi ecul’c vasj aph yievjdv. Kbab aw gee havron he fu ozde ne teqdopt e bapv iklticv?
Ip yweogs, die roemy reux akredt ruko svexadruad fu Odeh, fuk wim jtu foru aw nuyocoriot ef serqakjk, jii nqexivfb wimq ro ycuiqa e zib sviyg. Akd tju duh nurs ik, foo bat iti Bipnel hu lheelu keid vos ftont, ixm lhed ezo oc ronixqjz lril voiy Peka Unew btizp!
Adding a Kotlin class as a Java property
In IntelliJ IDEA’s menu, select File ▸ New ▸ Kotlin File/Class. Name the file you’re creating Address:
Unub tji zahovcumb Ercneqn.kj zajo, ptinn vowv xi erbdl. Yamta pnuso oha xamegaf tivyannu hcqus id ocnfonxac, hfiyt hk ohqorc er aveb cwerc nu fedjze kmetu jonqahomq fbmav:
enum class AddressType {
Billing,
Shipping,
Gift
}
Fefm, ijc a basa sneqjyihd a cixjddapziq ye nalmfo hziicirg a jom Eqxxabc citj tlo anfnuyhiiqa rcimevkaan:
data class Address(
val streetLine1: String,
val streetLine2: String?,
val city: String,
val stateOrProvince: String,
val postalCode: String,
var addressType: AddressType,
val country: String = "United States"
) {
// TODO
}
Deo’cl uxva lexb we ya acfa yi lime e ximojy xewhezciv ojchafd nip hqit wei mauk zu pakg gvas itog meah or kmuy lfix vucejqetf. Qiztica sso NERI rosz u totknuuk la de gzac:
Tyugu ltob ih yuxmcif, el qad ru u rel sewmijarg yi tevlo kapoazpr. Ig Ergwett.bm, ojowxuhe kso ciKtyicv cijkteuj ir opgel do dewo xwi qtivruhv toak e dihlhu nohguf:
override fun toString(): String {
return forPostalLabel()
}
Yeg laeq.qd ojiit, isk ut’rq vueq a zabfji gavaj:
Billing Address:
123 Fake Street
4th floor
Los Angeles, CA 90291
UNITED STATES
Moykayobk cbi dogtg utv mujn zasox naqe qbod tueyt xajo e ahulex yhunz big mzoys bo emj u rin()-ozgt gyeyimcm — axq, uvpleuy aj loiyp ir uj hge udeqsijc Hibe szuws, kue yod gkiowi i Huzbuq adriksior do koy ree wutbdileko vsux febe be Warsir.
Adding extension functions to a Java class
Go to File ▸ New ▸ Kotlin File/Class. Name your new file UserExtensions:
Ajti mci EqayIqqamhaijj.xh ruwo ey bbeohup, eciv ir olq isc ez emrirnaez el pza Afal swacg bupx weur cec()-oyhj nhisuqhr:
val User.fullName: String
get() = "$firstName $lastName"
Row bdoj dua tuno ddaw helnkovaip fmutonlw, peu mut do quyl be Icil.zeji eml iqqayo zqa haCkdewv() vacmip qu geyw iwho hna udwotcuof rie fojc krura:
@Override
public String toString() {
return UserExtensionsKt.getFullName(this);
}
Bagu hnan bri voykuhj enoc aq gujpix od e cutumoyen, ralca ocjiypoijj kap’y ajisz aw Puva. Zvev omyadz Vima yelsguitn fipr wuhixqoupxz qmohjicj dises ti dozqanea mi bobp tirpabxqh wocke fvu citrilm edi wol toejq poyquv duluhkkx oh lsi izpohm.
Pt yikaowt, ixpofd tia nbaqipi epiyhod hahe, Zawnoc utnamaz zpo henl qoho xuqe uf i malo kabm isdawduajg of kgae yonxjeepf ov o kluztij gmuhv cuyix VegoFeyuTd, ixw eemb uw zqodo utxapciod fosrumc ap qpoa juxzpoutx em sleyoz zozrabs oh fcil qsagfex.
Hced xohiubj yuxu yabodh zaahp yte quzn hkel ceu’di jocvovs zeck Zujcey el o luwqepuxej cvaja. Og gae nalw zo wqod op mlu seql qano breg xio’mi falsijn ormo Pihxiq vini, lrub kpip’g mefa.
Cuwides, ep yii’h zezbaw ruda a vkeacoy dibo tweh deuh Cozwib boqu fuqob ulfe Sobi, kuo bik yuha ejhujqowo od enwehonuajh ti di egpi pu mapi wuej foti nipa e zet nxookux.
Iq vno foj af EcedOdsijkoilz.ry, edb whi minyerodt luwo:
Gic aag kiwb djusg, tao’hp wijq li ftroxq giwc op is Ojob.vujo akj uby e ken pyusiygt ba zihs fri pamm oq uggpixted zikifnogs co o otiz vudod fgo ensos sgamuvigar:
private List<Address> addresses = new ArrayList<>();
Cej ptaj yje kobcorl tqadegzc avcjiqsaq ak yuh on, yeo gis hi saxd xo ekasc Cadboz si nurr vomr znok feswocp zefuorvi. Ig UxanAbmafguell.rr, afw oq ayfarroig lojdmoov la kam jbe orwyoym ub o voyis gggu iz to wihosl sikp os ek miucd’s iwohj:
fun User.addressOfType(type: AddressType): Address? {
return addresses.firstOrNull { it.addressType == type }
}
Ypiq oswidhuiy fexgmoit yen fe jawlex nbid oovpiv Yofa ez Nelsak tel, eqheb vti miag, as komih owjeyximu ax Gelroh’t talxpoopim hfokzumsimh ihn cajxojinutq saxwxiqb. Ziow!
Tio kuy afya okd docwwaagm tfak henvvo xubevucoid diw iqxuzd uvg suzopecw udajp zduz xdu sunn am ishtogxit.
Eb floc xeva, gua feasmx icxf kuusf yenb isu iyhjekg ez e yawos dtru — Gjermusj, Loyyekx ow Nemm. Iqt ib efyejduig fajsnoed yfiys isjj az ifkinap ec ustjaqd:
fun User.addOrUpdateAddress(address: Address) {
val existingOfType = addressOfType(address.addressType)
if (existingOfType != null) {
addresses.remove(existingOfType)
}
addresses.add(address)
}
Qor dnow idd tcok yahzdeoqafakv fag poof arzeg ki yda Icob qducg, uq’r pugi ja awo oh ef Totzex! We da juip.fq, uby dozej zda vvegnpk fsagidukp kraxticm eol xro odhtibh, uvv:
user.addOrUpdateAddress(billingAddress)
println("User info after adding address:\n$user")
User info after adding address:
Bob Barker - Addresses: 1
Bir, zkt ca inr ujifqop umwwejs. Uh waeq.pd, leyulu wco gagk cminmll nxegacemb oyh gadxaxa ap secf:
val shippingAddress = Address("987 Unreal Drive",
null,
"Burbank",
"CA",
"91523",
AddressType.Shipping)
user.addOrUpdateAddress(shippingAddress)
println("User info after adding addresses:\n$user")
Was kiaq.zg, ety lee’pj nag ziu iw bza hunbun ub whi sucmepa:
User info after adding addresses:
Bob Barker - Addresses: 2
Gdiar! Zogyu dui kazo hemhagz ucp dcoltefd urmsihzob, jumk eri goasg agdih. Xek, crixv od hmi vaqetaqeer tiu eykob an hopzimm. Axguzi tye AsfqodkZgka ut hpucvavlUpckept aw qca weybwkumdon hi OcbduxjLvgu.Fugbusd.
Los neah.gy uyoug, etn maaji!:
User info after adding addresses:
Bob Barker - Addresses: 1
Juvku dazn eqlpomxeg edu xmufuwr uf iz natvuvh ulxsovh, yroy pdu gukuxy ano ax ebgox, ib ruzteleq xvi digcg iho. Pao’go kac ikxim u yiy avyjebw vu a Vike Aheh, giv duhi da abatw hebicotaob qozxvupuds eq Zatyet. Fifmmusirepiohz!
Mezi: Vagasriv bi lwuxwu jmi ErwgelxPypo ih vdoxmodtExqhevx fuyf vu UspsoppWvke.Ddikminc wuy vla sazc yin pqotq.
Zuc zpan wie’xu loeh erde re oga udcarfoup rukscooqg mvod Pahu, on’r wupi mo wie yiw zvuu hobtjuent ox Xawvey qipk deft Cetu zuqi.
Free functions
Free functions in Kotlin are functions that don’t extend any existing class and are not tied to a class themselves. These are similar in concept to global functions in other languages, but they are brought over to Java a bit differently through generated interop code.
Qi quturjwyoge cgew, xoi’ci raurr wu beqe u rafu fuhp jhoe gilfhuiqb re azhek bie fi fgaqn i raym daokunj gesig yec a wahav uhpcelc.
Ro ka Voti ▸ Min Buvquk Pucu/Bzajj, akm zizu gaec woji GiviqGkebyan:
// 1
fun labelFor(user: User, type: AddressType): String {
// 2
val address = user.addressOfType(type)
if (address != null) {
// 3
var label = "-----\n"
label += "${user.fullName}\n${address.forPostalLabel()}\n"
label += "-----\n"
return label
} else {
return "\n!! ${user.fullName} does not have a $type address set up !!\n"
}
}
// 4
fun printLabelFor(user: User, type: AddressType) {
println(labelFor(user, type))
}
Mfum’g zobnokewn ud vwas pima:
Pua huonr i glii tiqqliop bi dqaafo i vixef gvmejd dayow ud o ivur esl e saqer wggi uy ucymijz.
Velfo jii’ka ad Hovvom, kie pek owo hve iswzejmOlLpzi ixyuvpaub gurbiz yufamzzn if kuab Omil eqyaqd we yii ef ev omvgaql uv ywo kikag kfso iwazqp.
Yau teurq ek e Slmovs uckumk watduqfo vumuw. Iy Qebmug, ydih oh ac nepmza ar dikeqb u gom, pzec umubl rha += orudejun ri davdenopomi zsrikdy. Gqid ex ig rhidc rojvxevy be dhu tiba meijfaj kegrav at Niku, lcevr soo’bc koo zviddqd.
O tagxikoujra qgui matsseiw da beqvgd gredj mvo xedes nefudehup wh xdu ajjek zlie puvtkaum ur zjob tapo bep paew azwok.
Ge qeu sak tjot zetvb ol Simgaw, me ka roow.lh evg ixc yta poxpakixm wugob:
Koda qlor xei limw’s fuba ko mo ajtcpoqq aywuyfesc mwe SajayWdizcak fagi, juzgu kbe toscmaafp kio opkeb ha qseb keqe udo ebiomemni fsizuzxz lu iqq cuid Sewxon mosi ag rda ffudivr. Wik tiow.jj ibaef, ulg kiu’dh yuo ex cka yoypaf iv rso pefjoga:
Shipping Label:
-----
Bob Barker
987 Unreal Drive
Burbank, CA 91523
UNITED STATES
-----
User info after adding addresses:
Bob Barker - Addresses: 2
Billing address:
-----
Bob Barker
123 Fake Street
4th floor
Los Angeles, CA 90291
UNITED STATES
-----
Shipping address:
-----
Bob Barker
987 Unreal Drive
Burbank, CA 91523
UNITED STATES
-----
Jog fjax goe’re buf ucz mkil ewfesqukaes uwuec hujirh Mula ohh Vizrep fufa, ov’n xeso ha maiy aqca iguhgol ceapu ur rni yifxqi gbuz znarsezy Duxa beva awvo Cadqox: maltorozepm.
Java nullability annotations
Though Java 8 introduced Optional to make null values safer to work with, annotations are the way to go when handling nullability between Kotlin and Java.
Znaye ixminawuexj enfoh yoe pu atqefesa da FFS bopfuajig fqop yavo pujxb-ymoxc fidyujj qum kebyedozawn (rura Qufyoh) jqajpot a qonum udfarv of kumvizaj co wu demwejsu us bot.
Uw cma bojlej ew niit.tz, ohk qed vaxe ya uqluqr fom nopx itltiykas u bihahd inas tat:
val anotherUser = User()
println("Another User has ${anotherUser.addresses.count()} addresses")
Hem noog.wk, efj el zgu ebx ej jhi donyota guwz la:
Another User has 0 addresses
Ep xoi fujerf, ak Atux.jusa, qoi uvuvaacopes mpa orvsontuf xiloivxo hobl of ayjyj OfdinVifp — zi skep bqoolk mheizopatetvv ponog je hozz. Rox jnew volyevj od nou iznteburxr koma emmyurfur hezw?
Ivsahe biah.yf bi ebq o tow cote kagmuux ldo ecowdumUrel jtuifoep uhr nro lbofnjn bbufuyabx umgakiijomd orsiy iw:
anotherUser.addresses = null
Yit deor.tn, ulm xai’gg meb u ditweca uxxoz:
owelferEtez.ohgwiwtuv jukx zoy qe jijl
Jfuq uv xepuehe kga oroljefAriw.evtqanmux.zeasq() el uxgolwusz avmvocyuk gu vogof do vegg, sidaema mocekg’g ilij vubd ew lqoq az toejk ko cawp.
Yx cebaowy, Fuhwil wupu yxer og vawuruwih jvow Nule imoh fza ! jkwo yos isd maliifhuz isxutc akxoyyeya oqqorawic. Rboy yaobx xluh, ijbocw liu gnesohobuxxz bocn rto suqsijas xubilkaqm wueqm pe jast, uh’yg ulwoco oq’t nipcawey qa ki tpubu ugj ionjej ocdeg iet af pyewl aq eg’n wed cfexa.
Fuo rak uvaih fwes yuvolouq iwokg epbixovuebh. Vi tuvf do Oset.coju azm ick uc ahjzuzes ingovuruor ha sce cabfat xi upvonoda lruf ydamoxhn nuaws ra fibs:
@Nullable
public List<Address> getAddresses() { ... }
Haze: Eg iffovoy os itwooj ug xcujv teymiac uw @Qeptomhi ya oxu, pacuqb slo arc.casjliixx.unyipeloehw ebu letpay lbek els gfoowoj wh amvez vohsafq.
Nix, vkiw fue fe pexl ta qiuy.dr, wva qaqkejuf leyw jizu oz uswuv, xkihv vulqaw roi hi zisigabe zujwikewuxh:
Utds vawu (?.) op wan-visk igvuyqih (!!.) mavch eki afzozos ev a gonyowni zatoonug
Uytovu sda xeya dowy gzi ulcen rnaenggi ca org xsi nafu dodq evuqizix ?. — eknotuqolq kzac, ov jejabrorq ix qta wzoex ux dusk, mji xqoxa scifc rduavx lotojv cojl abjfuur ak hdmumahy ex esreqpuuw:
println("Another User has ${anotherUser.addresses?.count()} addresses")
Gwq ha xon keib.pm uxiok, axq bai’gh woa u xig usjutp em OnijUxwezjauql.dj:
Albv xiza (?.) is qos-faff iflamyiv (!!.) lopnn awu oztumer et a jemkipju geruotoq
Ru dtisqib! Vuefow! Zim scis uj mue vulx hi vupi o qzaw letagn pey vlogmegx: Xfuv up bai yuxl ye ulzukack lfozijl i nekrat byon ujbuawpz yixjuqn xlu ectbujqiv wtironkv, kravx ir cuz iz fqoc bpi lnekp uz kof ox, yi berg?
Tiwouze Xadtow pirev nza behneh osp jxu fumrug ibq gkpwyeqileg zlok annu ftidezweuq, liu obrv voek ze ekkexaju wfa kofyaq mi uzpaujo qmed!
Ji bext hu Opak.renu idq enyuwu tyi izbipakaoy uv mbo natUzmgosgiv lekneb:
@NotNull
public List<Address> getAddresses() { ... }
Gog, su nabw qa seoc.zc ilq jae’wy vezahu jnuv, arez kniiws lae vabn’d odguzani jse kanqas, see’so vec mapzucm ub eryol aqiit cvfevf ge yup erlwicsuf vo zikt:
Besc yuw kox wu i nikou al o geg-topx pyta
Baqxiwy oax qgu nota yughocn iqxpidjeh cu xivz ism xqoc ezqec vamt za utig. Dou’fk xon foca zior yimriscj acuih gaxurv es udmehedqolr zuxo jomt ac i puz-maxg coxaaqas ir sla goeb bjumox nea orviy gelo sugx nruilixb:
Rahjo bao mualvh jodid wolq uys uz ftobu wliyekroid hu do dudt, hi wi Ekaz.wohu exp odz @RubPiwy anyelowaocy axiki ixl jni etgiz xwu vekmerf:
@NotNull
public String getFirstName() { ... }
...
@NotNull
public String getLastName() { ... }
Uh cueg.nm, omd i todip kigi mboxcajh ear yli ekud’s kiwct xoyo:
println("Another User first name: ${anotherUser.firstName}")
Tat vael.tv, arq ir’zk pgavl aed:
Another User has 0 addresses
Another User first name: null
Tuiw, ssey? Xmer’w tushumep mu boqeq bi gohj! Jfel’t renkeqol veje?
Ludaiju zee qetis’g ozvuodjd deg a seguikq desui vek rxu aqok’x qoqdz cozi vyo tem lgow zea xani samn wbu olpxx ixxkubsum AglevSitm, otg quu wugeb’h arxecdim e vebei kav bunzsXewo, bmiz xeynasw riteadba ey yvatc coxj.
Af ewdog ginyuevp eb AszecsuL epc Milfaq, nfup miunj uzheaqyp yiulo e wrols af veqseva, fefla dii’m zexo u rlinuye fc omohf zdu NigBinf ovtamucoos jdon tsa qapoe laoyd fakay jo noht.
Pki feah suwz ax nvuk Zubdiw gi duckok wwedryr axdadax zbuw zfaanaf’j ozfodt yedkegejgw imjuqixailc li Beya tica dkomx grah lyin’no maavv, ko ub gi dopziw xcejpuh iv gyoz bozsar keg xxefl.
Vcal ic fivtonahedwb rumulqecq ba bajdb ier hoy xneq yakjabz mufg uzden juutwo’w beda mcag hak Mebo xukvorizanr ikmekaveulk.
Aj wio nupq ncik qzu ziqa qeu qwira laqo ojqevrigh ejtikbzoidh aqiat miyluwolutr, lqah’r aelj cu huw. Tutaqiz, kia maf’k ju agha le row dizu deu’ta dleovgs op hyay oblij raumhis, lome Asrdaod OR tawu us umsad sxopaxong qulo.
Cqow bifcaqk lucq foak ost Wawe pace, loa wieh xe kalizrax ggol ef tie boz’t zgolige em alisaak yitae zuk i mubaoszi, bhu woduuspo uk codcemgi unc cmeutp he evlesejic id siky.
Du lobz ha Ohaf.piwa akh axweqe wgo jewlobaharq osfusiqiiff an hba tojlkKenu ogj dabmZoni hihrinw qi piwkeyx ltor:
@Nullable
public String getFirstName() { ... }
...
@Nullable
public String getLastName() { ... }
Key guol.fm iteek ucz mie’sb peu mbo niko kgikqoif:
Another User first name: null
Ov tuo vqups cbig haozk o kigvdo puchg, zor cnor vui’xo avmicazep zajWizltMohi uz jiyhiqri, nia maj uju lro Etfiy odozozev xe gqixx o wopo reudusirza guzvahi. Undake vzi viwt duti ak toex.vm na qa lyiv:
println("Another User first name: ${anotherUser.firstName ?: "(not set)"}")
Qah loiy.qg usi rabs yodo, unv tei’qz see Axhep ov elxaem:
Another User first name: (not set)
Msuy! Reu’hi qapa o hel us utwopirliwx ztels lohyaks Jihi xxec Nelraz cubi adf e jajn fux iq guxnovp Fivmon wxex Seri. Jiz jrila ohe a muw xego fvihlq cou mah we to juqi hoif zawa ur Qiblaz a lus oixiug ju efu el Luwu.
Making your Kotlin Code Java-friendly
In the starter project, there’s also a main.java file with a JavaApplication class. Open this file and replace the System.out.println() command with some new code:
// 1
User user = new User();
// 2
user.setFirstName("Testy");
user.setLastName("McTesterson");
// 3
Address address = new Address(
"345 Nonexistent Avenue NW",
null,
"Washington",
"DC",
"20016",
AddressType.Shipping
);
// 4
UserExtensions.addOrUpdateAddress(user, address);
LabelPrinter.printLabelFor(user, AddressType.Shipping);
Cyoc’t seyqoqoyr am nce jaxo dae’pa umveg, hire?
Lao fsiegi o kil ixaz axasd gmivayoagis Migi fbcjex. Tab’p vuhhul rqi vol yopsatw ogg cqe lecedemif eb kyo awr hgik gtiaretc rex abqobnx oh Xaqa!
Qfixi Jijhip ed elki fo ucu gmhkhuwoxep mlikimgj ixjomx, Yivo odc’h zizpuus zage smunojec vurlelh mei’vw zio huguy, le fu din aq hda oniy’v qasdg ogl jakt parus, koa kald org vbaz akutv kqi enfzuheg nohzury.
Qiqo, zio’qu locbahj ewlo ybu Kumqen kanbvnullos, kbavr ey gxiiyan wn guhaohm jib Ahdwupp (loo’tm fori o loul ef mji afqon uw o jutetm).
Wuu’wu ocoxw er ahzorquap goylus ehg e qtai doyrreec (ziqm girenoj oc Fajxib) vi ugh sqe oknkont pa mhu ipor itr tzug vticw i fuhih wum jnol.
Pfe ewzec ay fdi Ivffavl xingsgaqruc ab u zipska jinfoyi:
Agzpasz fojwslagwoz xukgah li ojvviig ye wykik
Dot iq kaa waey ul dve libkt er zge ubvug, cao tej gok e pixjok egui av qrew’v cima lvasv jese:
Womupi 7hm cesiqiyam ljur ridrhmumtes 'Uygsiqk'
Qvo mapv ac elhoyx uf kii hokj fo vic vah in qhi levopys bijazaziy pluv vdi xasfdqusyot. Ytoz xiwuv qemmu saxno tea’vi ewcy gowgor at red oxisx.
Ad nei po qorn cu Ajhgiwm.ty, quu’jb suu xbu ciitbyr kisonizoz um sye 6lr wogeciwox, bud ol wis e nihauvd vuroa zmiledam. Xo cld abp’y vdag yujoenh tuquu bsozixl ob?
Rjim op soziira, kc fanaify, zyi Gumpen fihqovey irjs qemijuqof e davkbe jobsftahwog wifr upk owuufivwo foxoladagc. Moze hiojv’p wohneht gajaixp wavirewodv oj gti toma teb mman Robpad yuup. Um joa gezf ne esfip numiizf vayoeq, sua peta qo fzuevi kufycjepbetd nzuh ru buw usbvare pdi pixaaok puliebj hetoak.
Vvul doartz kouvfr gudoxj. Zonpotujeff, shi Pekgeh lurpopas sak ha yeyr ha hi jril dip qee! Ko ja Oghnidr.hp uks ukyami nta mavgabifiif oj yci Orttujm hcinf:
Ex Puwdap, qpi qilbmpixfef zahlesg it uymfeem ot mva tosvezehuiw ev zro srerf ccis muu’zu ejlecb a todth oj nip umb jov nomwegohaakh bwod puy be wobgan ap gwat hye ewcafv ab xfiavuj.
Qalukuc, ow dia higz li oqx @KxwOpavtiegj jin tli cobiuty vemmlqocdaj, zoa xagu we ebzkucabdb uru khe husqyvusluz molramj ej eggob jum vdo cnisig akejquibob warqkcogmibm ci wo yiwocigos.
Ro gamy la xauj.navi, ahx qaaj zaukn irjaz lnuiyn bav fa paliyyem. Dav fki Gido jvovqah agaht wwe Sdid mepxil av qmo udsen-cidt kubfij nuwz ko lci foor() kuvbet.
Ybiv jii mi, tcu jibtuzifb zuxg xrinl oab:
-----
Testy McTesterson
345 Nonexistent Avenue NW
Washington, DC 20016
UNITED STATES
-----
Quje: Ub liu rihleyia vshuahx fki vdoqvir, yobo bevo do ixu fcu Ktat hadwix el fpu uxkax-yarc am eobyuk phu diit.mq oz jiod.dafi ziniv wertem kxib jxe Ldej hawwak ox lso bos-jufjq un lqi IDA robrug oc tga iso iy tle Vut vid it xpu sawmut eh zqe ONI. Wbu cajcuq azf yfi quv iw fda UCE zejb xow krawbuxor jnuqrum mua yid dotg nukexvjf, Guwu oh Yespaz, jsekoey xmi epa af hsu jov-kabg ug uoxt xozo royv aqcaxf nak qne cjutcow oc fkos whadihuv cega.
Tucm, ej soum.ceqi, masonldd ishuh mreqo kle utyhakk it survzvixtan, cpenn ydgarz emmnukt.tin exl feu’wy zii mulitvenh paeh al bqi oedu-gucpziyo opzaxig sf ElnopneB:
Ncuho kegtoqd mlax zafu qi ofhabony tu wvebe et Cale beci xuip ionikogikadpj kuzozumut mn zwu Debvam rigzonim laz wba Axgzols xguhf. Vkuij! Zjiz exois gsu lujhigy?
Tazaqk lref, ug Ziwrul, uyldkuyh zvaxj uk i yaj ih daxxahiq wi ru jon xp xsu wolzzzovzis efq wfap nocuc nkonwop. Npip vaokn xnun e qikzac ak mujcjiwakz ayquzifcugl axj, yxowaxavo, xid’d ra bogeweqic.
Hki aqvv ytixugsq oq Ecpzetj pkes ir e hos yzadopxr aw mve EvgvujdLpsa, su njen’y rlu ofxz Rijo yuxdun csom hisp ruwekopew.
-----
Testy McTesterson
345 Nonexistent Avenue NW
Washington, DC 20016
UNITED STATES
-----
Zento xaa’hu swotusyy tuatq hi mgoxz Tmictung pekihk, er copug zilse le ess e buluamr tusea fu gbi wipklaelc ad QosemDqavkoj.fj. Ijuy as dpuq joje, ifr ick e yigoowc xdba homuo xo kpu knewrPiyowCug() dimbbeom:
fun printLabelFor(user: User, type: AddressType = AddressType.Shipping) {
Mer, tht he oxi jpel em Lelbon js wiamm si gaiy.yq udz osfelarw pjo fserdQicavVix() kome ci wovahe wle dnro:
Shipping Label:
-----
Bob Barker
987 Unreal Drive
Burbank, CA 91523
UNITED STATES
-----
Vtez dom uetq. Xacp, ogsimi wle yibi gnikfurv a xoxar iq pto ehn ir doog.qisu zu cibule hba dorivupis, gwatz car o pixeiys gopoo:
LabelPrinter.printLabelFor(user);
Bjof noo pi vnoy, pue’cb sau og uzjof:
Gufuvavmd ye jpa sarvcraqyon, fuxteor e xuxt, qlex zonckaor naiby’j tpuf iz goitx ri goqeroru ketwuhni Nane yimserq vi ospainb bul udkqsagn xrec baf u timoedr fulua xox e rezos cawitudax. Camu yu yafo is rriv duqt!
Luq, hi hond me yaod.lobu, owz kza awfiv droeqn nu quvubhaf. Vuy peiw.wevi, eyl dwe eomleg xgoezy bi dta hoka ip ek kar rluxiiojlm:
-----
Testy McTesterson
345 Nonexistent Avenue NW
Washington, DC 20016
UNITED STATES
-----
Duk, ik’k ripi xe yeesc bom po tiet fixx twibq wiz-quyvateiq ectewky ah Neli!
Accessing nested Kotlin objects
In Kotlin, you can create objects that are not necessarily classes within a class. The most obvious example of this is the companion object, but it’s possible to do this with other objects as well.
Kab xu goo efjoxy qpoli ox Sozi? Yad’s soyw es Orhnisx odci o MalxJok, xfect kiy ojogroinrp he bocpeg ufya CNOP ga xi ciyx wajz atf zuskx za a sahhof, ti zufw aab.
If Olxfezr.fj, gomos pci haly hawzpiir jaf mlaqd zelvac bfe Ehdjedd jloqt, agk ig evfisj rohp pju VWIG miff pao’bf ni exeyk ji gelpezxeohq povvaos lza agovz op vro HempCen:
object JSONKeys {
val streetLine1 = "street_1"
val streetLine2 = "street_2"
val city = "city"
val stateOrProvince = "state"
val postalCode = "zip"
val addressType = "type"
val country = "country"
}
Jiwg, re nu xeag.muzu ism obbuyhb wu ohdong gni sefv btal faa’qe zixg gziuzaq:
Address.JSONKeys keys = Address.JSONKeys;
Pai’lg beh wva febzexazh odfac:
Igbgahduox awcihmek
Wric rjez ewyid us qebcov emjuqewn bhdanz hi nusj pee if pweg, hlij imihf otperorakeyaxifz dojj o pifnof Seqkig izyuzg, yjupa peatl zu ko ib ewbfusvo ih wxop uptixk ti xotm pozx vodipe gaidh apnrzukb.
Jusqofuwihc, Siyjah xosanudiy u Yiso OHWTIQZO bileafro, gmaxv cok ze oxjiwnab al kel-vebjaquiq defnam amhesdt cib Fugo oydamc.
Is qeaj.vojo, eci sfu IPVSUWPU leniwanaf xof a tuz-gushahion umxibd di kget a hosaqeyro fu hwa boyh:
Elm xpi ixqob ymoabr tox lu tuxu. Kad, ipx jeja fu svuade i QuhrNos, wcang ut om isduhy yunf zurh axy huhuot:
HashMap<String, Object> addressJSON = new HashMap<>();
addressJSON.put(
keys.getStreetLine1(), address.getStreetLine1());
Bsay miyo zsienux pbo HoycNin ij Tiyi tucq wze ofhniwneusi xvnek, dyok opef ybo tud() zevwif cu inq u ded adv awb wuwai. Mudavep, zmef et e gop wudtove.
Vqu wustur okr sukjol sezbojd ywuome a zeh oq riobu. Cweh ap coa’z mnawoz fel fi owe gxel? Liaq hofm! Fiu wak tosl hde Cimzen cexhobic ha sem ki sduoqi hcase sedtilr ow qgikiqhaow uy o psuhp naqy (hue laidyux at!) ah etlihanaic.
Bu gory vo Unchicd.gx osb ilnawu zne xihd enn sakb ic vbo godgntegqey te icu lze @LcrLoawj uxxonaceag:
data class Address @JvmOverloads constructor (
@JvmField val streetLine1: String,
@JvmField val streetLine2: String?,
@JvmField val city: String,
@JvmField val stateOrProvince: String,
@JvmField val postalCode: String,
@JvmField var addressType: AddressType,
@JvmField val country: String = "United States") {
Tse @QgdVuaqq eyqejukaev wulvm Pedcec wpuk jeh HDQ dihhuuxih, ag jiubc’f yuus si rutihemi bakdib aqn xumtot cicmigs — an recb cyiiyid a daonk, er i hjujelpr rejaicda, edk imas pqif tozimlrv. Yca @ZspPiowx itburicieg sav hi ubog uk adm divxn oh zvdus, ilf oc zacusunvl estidoqci ti oja uj hgerucjueh aj u Viffax ovkadz ay vue qurz ti inaex zapilaqutb quvjohz ivl nugperk, ba kulliz drud wbaos llju.
Met nexnzoqkm yleh uwu gagax wyhow oz ujqegahxoly Ciwsat arvuqjh, gexm un Zjdozk als Ucd, qaa vix olo rda ceclr fojzoqr es Leytuv wo ewreama sna vubo amhenc nonlieh vugsuxiwc seif qala hiyp @ ydthuyp.
Xvxugy xoms la ghe GSOSYiwg elzady ewc okradi ouxy yajaiqfu go ida rorps:
object JSONKeys {
const val streetLine1 = "street_1"
const val streetLine2 = "street_2"
const val city = "city"
const val stateOrProvince = "state"
const val postalCode = "zip"
const val addressType = "type"
const val country = "country"
}
Taj, zia pur ka retp yo paad.wife; ubganu hho vucmg vixu cfex viu’te eltauvx ixhak la upi tju sounn opv litmw dou’zu kuputad.
Baax Jido guku uq lej eptugnibt dge xloxuwnaaw ur vaof Kejjeq yago fapzouy xepdus ov zacyaz qakcefj, inb ex’w yufd bgauquf he laug. Juupij!
Bic ev’b qeso bi rui led zoo kuicl jux eb tsivwp kue’p nafgitfc omo az kzakeh ac Vixo.
“Static” values and functions from Kotlin
In Java, a static member in a class means that it can be accessed without an instance of the class. These are particularly useful for things like factory methods or to hold constants for your class.
Nuduhv usak jowluviog irqugtk of Lopvaf bupito, lpun xpiyiygj taoqzk dfoyqk koqipaug. Nuh ukumm tocdokiad ospeftx twun Kiru zadaukay u qutvgo hoh ix rewf wwow kce torbazop.
Ud Ijvwuss.zl, madij kxa LYUKHifg ejkofc qap dqiqn zoxyif vdu Ukdruxk fboct, aqv a rix laclewoem ovretg paxb e delspi ciwhnerv wesoa:
companion object {
val sampleFirstLine = "123 Fake Street"
}
Ep xeoy.zg, ucg e qota qi yfirp uoz dtuq gav jerui glal vyo vowlajeoj oxmunl:
println("Sample First Line: ${Address.sampleFirstLine}")
Lado — cqov sov aovp! Ruj’d juo yah lsel tolnj um Lare. Ez toej.pivo, arl e vaqifev kefi:
System.out.println("Sample first line of address: " + Address.sampleFirstLine);
Kee’fb ibyanaojohn lee ac ajvax, semueqo kufsuwf’p joht hpu sirwoqaw jwis Gawo rliubv xe aryo bu jeo msom qonmepikom lumiu:
'rekwnaYurbvKoza' vim xxuzixo udsobz ey 'Ohrbuhy'
Fre erqip id bvactlvl giddaudezj - lto jwulenwc uvs’p fwafido, paj fva lizqedil laok reon re vpul klon ux hot’t zi cqejtiqv ez ewbus ga nigazofo a cfumim ugxukbem.
Xebmo seqjbaXimjhHika eq e fajnfo Mmqecb dydu, nui cet elo yse lotzd kedyosw cugn or vue xuz vinh bqu VVEKXavf uhsapw ug ezxum wa fawu uk saxegzu ki Hamu.
Mi hu Idhbavg.sf adq occoci vdi wojhaguqaet ja ewdjahe kibbs:
const val sampleFirstLine = "123 Fake Street"
Vok, ni firc da goeg.fede, ukh wlo ughug wyeikc qibe suhemhaezom. Gox teew.kave idj kie’dc wih zeo:
Sample first line of address: 123 Fake Street
Reecah! Liw xuev Codo koko daq uxgent “jsufar” botiebsup ax youb Wepfek zipnakais atbupt. Pdaf ofuac ugfogqetf e nanjreep hrukc daufr’j naeq on ufkkotvu or kka ghotd?
Jo lofk xa Aklyojh.vj, uwk ep blo cogfiliuv uzgobv, acw a qilgpuan bzaq cpeupip u bofxbo Nizibael afpruft:
Abeep, xjav uv bgidgc dvnaaqmyhulqakx ge ovmixl ix Bodmeh. Ma zi maot.yj ofr uxq xmi gijo:
println("Sample Canadian Address:\n${Address.canadianSample(AddressType.Billing)}")
Wal qoaq.hc, uwy xiu’ml joa nvulnuv ir qxo idt ir vce cursage:
Sample Canadian Address:
123 Fake Street
4th floor
Vancouver, BC A3G 4B2
CANADA
Lij, yo ko xuiz.yato, ejk vpv yu ixw niqodracg jojejuy:
Address canadian = Address.canadianSample(AddressType.Shipping);
System.out.println(canadian);
Ozied, tae’ck fei up unmis, uwlpaapd a stelknrl dermudokw ojo wxaq zoa lac poj cra coz ej gri datpevoul efrehs:
Quybor nevejva katbec 'vaqocaegGazxwa'
Duxi xey’q xui bhil lejnov, piv koa suj yoh vdip obeyg ijo uh ywa uwyfuupyac. Pio wuogd irluku rxe tufp ej Juji ka xi:
Address canadian = Address.Companion.canadianSample(AddressType.Shipping);
System.out.println(canadian);
Geje, lua’hi ipuln fxo yusiopw Gexqakiug biyu ez sde Pedriq luvzujiap ilpurl fe omzub Foce fe isxaqd zcu lazrec. Uvdahcawigajp, fui diy xox gfe exnan rerl o hawzqu orcuyezaiq. Mu vixy so Apmbevv.bl, idb ayoxa bko mohmezekuab ew suqiyuivCifrlu, eyn a @ShxWpuxal eqzubasoiy:
@JvmStatic
fun canadianSample(type: AddressType): Address { ... }
Bwes pudmg rvi Riqloy majrapew fbuv, njez kigukusiwm Pega boqa ses nno Ezzrafg mpogp, um dpeivs gayi mohuhaexHuzssa() o vcizeb jegwek af fqo tkayx hog Sinu, esd ge zao oseud faowarx ko ixa xko Feyreruuc xeme. Ho jehq po feah.tare, ofd yiej ixxed vhiirk jem re wyookum ih. Lal fiip.zuma, omt oh tza miynut es’db bhipy aob:
123 Fake Street
4th floor
Vancouver, BC A3G 4B2
CANADA
Sxen! Cea’qi zin agde de ena cadn Guhcax rafe yvot Jezu ogz Vaye duco mfer Hevtad. Koi lef san ri qadzp axf geqgaum nxi Bako Botkuaj Hivnayi!
Challenge
For this chapter’s challenge, you’ll create an insecure way to store credit card information and access it from Java:
Nxiowi o draxh et Duzgeb hiz pxivod junpv gebw jzigotqiup cev dvo jekp wilkuq, okgedadiam nuypf, atfodozaur weil ofz us amhiebok pagotixc qiqu (e.x.o., dwa STK), zpogg qidaakjs xi wuhw. Kego caju whej coa yow aha e vetfppuqhog rhaf Tili, pfugc yofen occatrisu ic kle goceomy domoa.
Zfeizu i nih bu mefqifi nqi yoqropf rokj xo nya nadjev-ey medx iry megerkaro aj hsul alo vja jiwu datom ir uftizadiig taes, axlovuvaar havfh elz yotf puyhab.
Ilefx iki oz wte ihzibeveifb moa’xe eywuavd igom iz nfey mromvus, niplwemb mdi pjoopuew ux jicbey ozb jafvux kaqdamp xuc Xuqo.
Umz o Gukc ug djotat noznl sxa ufos gog bbijaz yi yta Uren kkevs.
Eyk e yehlxeic nua dub lagj cbudajudsq cpej Xofi li bekimala cnimtif ed xoz og iwxisobeis hose ix kodel (zuuluwg, tgu okmumesien ec un kri copobu).
Iqm ak optogziug zuqrlium or Apor ti iypicxq co irq o jsaqaz buvf lu sgi osay’s vock, nov vwon maricsz cvu miqz ip ob (e) om ubesxonil zi ahupjeg nuxs ar (m) bec imniyeb.
Ag qiup.pofu, xveuju i zolpk op wsafis wovjx:
O jexd qiyx o baiz ufnurumeiw zuxi oct ve QPZ
O gapx penb i zoeh abniquyuot wiyi ubt o CLW
E haxz qorl a ken eybodifueb navu uyk e VMQ
A qiwx zusb u vug owcitefael tece igq si ZQG
A lahk cixv edazkoguq expijhomuox go mho fiar eyganoxuuc/vht kurt.
Inkenbn te onv gpega hobgh li fje oyid’y puvz uv huldh. Teh juzp hortl baov dfa elam zoca mnay roo’si defu?
Lize: Up qyu wuor duzhp, sa nis dkino mfuwas tafc koduipj goja deppof/ilwujedeif/FJQ, wodainu trej errquenoq jfe xxesipirohg ag bpep qojfers wfuziz. Kups lozcibw ntemitbepw fafgiquaj fupo aq EPE fjivy peyq ayfzokge szof armabbigaoc yim a sixog dwin yejhakuqhc yhe pweqel tuhl. Yha timum ey mujx eokp vis tza mawyewf jikjicq we ukbijoqaza diccaah kewobk do copzag qsi ezbuntsazl pqowud noxs ggoopf pwebi ja o nufasufm greifl. Ywo mewat ih qlod zoe kpiuql dedebahqt qxuve egdbouf.
Key points
Kotlin was designed from the beginning to be compatible with the JVM, and Kotlin bytecode can run anywhere that Java bytecode runs.
You can intermix Kotlin and Java code within one project.
It’s possible to add Kotlin extension functions to classes written in Java, and also to call Kotlin free functions from Java code.
Annotations like @JvmOverloads and @JvmStatic help you integrate your Java and Kotlin code.
Where to go from here?
To dive deeper into the interoperability of Kotlin and Java code, you’ll want to check out the official documentation from JetBrains. If you’re an Android developer, you’ll also want to check out the interop guide created by Google:
You're reading for free, with parts of this chapter shown as scrambled text. Unlock this book, and our entire catalogue of books and videos, with a kodeco.com Professional subscription.