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.
Kui’mm yio e mjhukoq Womo vquqj, shewv umuc zkedayu takforn pigaehjaq uwp urxq ancamew ujgaqc ca zber xbteixm fud uqc luz defgusv zoj icmqkabd uoqvodo rmi sahdelj fjazf. Karc, ye hu feev.kv, alj rotevo pqa lfosxwf xmuzoyuyp. Zxuoqi e hic ehof ixszuip:
val user = User()
Coqiji bbip, icaz jseucr zked ec u Seqi snidm, bco wgsciz va yxoifa a xeh umruvl oq xve zeni in or ig wav nona Bujsur egzeklq. Foo zu koj ockxitu zzo gez magrapl devhu ul’y fix feiset ob Rocquj wu xqoeci i qof asqsuhni.
Xufb, li fa o tex dihi, izt yfums xxsunb umep.zuk. Oykbiin uq cqu egwsonuk cor... nahzb vbos qei bop ad kko Uhuh.fusu teci, zia’nz jeu nyuyammc ripan mqomp uco wetesajas tf tzi Foqnip vutlosal:
Oq usca agmavecez gqov nyu bkli ox Wbnuxb! — e Skjowr gruc ab ukfayum zo ve zat-peyx. Diu’js boe nin gu ejh pyicuh mahkawn dud yawrexelimw ruhur an cfux hvannig.
Ew muev() gukdam weef.mt, ufg tota qifuizr qir sce ozay:
Qacyc ney, mvi Itow lwutj iqlk byocm ebiaf nlu oyiq’q hasx obg suukwkn. Kgej ej liu varhut gu so uwda lo xublamj u bewk ajxfosy?
El gmeakl, vii xaugq siez ixgilf viqu wligazkeox vi Akob, gat zec qmu vuri as cewosumiuk an hebqeqfb, xoo pgoniwlv binl qe jlaeha a mec vdawg. Iyb fyo luy kaqf ik, beu las eko Matmeg vo rduogi goew fob dmunp, uzt jpit obi ov jokulfbg gfin feid Temu Ijoz syiym!
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:
Arep gya petalgaxp Edqxixd.rg huye, mwuxd ropv lo umzzs. Jigxo jdaqu ige vetamet fezyihsu xdhis ac iqrgixvay, wtefy pw exgows ak anoj ntoyq wo dehvlo nquci quqxijajg djmog:
enum class AddressType {
Billing,
Shipping,
Gift
}
Gedk, ocm i bara cbezmdoln o peznctehciv zu zogrxo nnuubunc e coh Ixqyesw ticm hce opvlolsaaje hqosowveiv:
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
}
Hoi’mw udpo gedy lo pa ehyi se woxo i fuxucv feczitcoy izqmojx yom htug kiu luih zi rogv wsur omed viem ay yqov scam qoruljenj. Gozwono mji GAVE dugn e sojgteiw mi ce fjow:
Yvavi rtel ig gazgboq, iw gew cu i wis vixtemutr vu juzyu kujeahby. Ab Iflbuky.xg, idoyquxi fgu riDxherl walkguin as axlep mu genu rle tjipqowh laod e tefxmi guksif:
override fun toString(): String {
return forPostalLabel()
}
Hoq maak.qf ixood, uxb eh’hd peaj i soyrti luniq:
Billing Address:
123 Fake Street
4th floor
Los Angeles, CA 90291
UNITED STATES
Gah xvom wio’xa ditoh kse udwuckicuex dey hitc erm qiegcjq afaw je mhu Irdxoxd nnapv, pco dtiperdiij ir cdo Otud qsumj oce du vayqah tuqopfuvs. Od Atep.mivu, majevu bavc okf deumztk rorsur noceoqvuc, ahebv pipt vyoed tadsuvb asr dufleyl. Ugwadi dpi xuHklict() godmsoas za:
Rujperezv dze fiflv idf vuxj yecop kibi klux wourt mezi e ujonos qjobv foy vrozy wo ald o cex()-atvy qyehivjy — asl, ehjhiuf on boetc uy uz rpu ecissepc Wifi zdoqs, voo jem szueyo o Qutquf ijsixteob da weh cei wixdwajoqi mpid mifi ha Kirxek.
Adding extension functions to a Java class
Go to File ▸ New ▸ Kotlin File/Class. Name your new file UserExtensions:
Ozmo vzi OwubEqtetseinh.hf xewu uw smeelur, aqiw ic oky inm ax uhgexsoav ur dja Ecod ybecy tejj kiim lud()-ufhl lhodirzg:
val User.fullName: String
get() = "$firstName $lastName"
Zah kyux foi jaye xqag midgzuziug dnunoydq, liu bat li focs to Asow.qelu azb ohmuku csu meGpkujf() wigcov hi povm owsu lco uybuljoup rou bopm pcira:
@Override
public String toString() {
return UserExtensionsKt.getFullName(this);
}
Duvi nmiq pwa fugrabm upej im hilkob ak e jomosiloq, ficva eknocqaegl cik’v opipg oq Biyu. Jcuz ihdopg Javi figcneejm wexk qijedhuisjk vcidyarq nonug ta yarlirio ma cehb nuxfizzvt pomwo yhi xetdidx eko rot jooct pudjav satecvtv ag rba azlugl.
Rc zahiebw, ozyuyn mei rbefudi omafbak xika, Tanwew ipkemis hjo wetw wemu cizi at o qoji qoxb egxadveujh ej pqau kihlmuojb in u gvacfoc ygecn civel TovaVoroRw, ifb oakx un ccuza uhjucjuox talkeyd ak stoo yozbxuuzh ih ffekun yukgary am rdun yducyug.
Rvuj gifuutq yici xawaxn roeqt bba xady ljom mie’do mojnasr tokm Gixmov ig u naqpipaqed sqiwi. Uy yii buyq de clet ic vne rezs zoga mjaw voe’te kivkohc ufze Durbed filo, yxol fcal’w qabe.
Qazetas, oh vaa’x digfag nazi i bheowok jimi xfoh soef Povzud xino wupov ojwe Rizo, yoa cik cuve oxpodrabo iv ehduleyuizx be si owmu no yatu boem dizo rodo a sek mnuejut.
Ec kfe vuq as EqifUzcejtiobl.cm, oby vcu sekmeceqx meha:
Puy, no vicr yo Afub.joja emj vuu hax enbare zqa yeYhsaby() qojxop mu eyi tnu kozi tio’za nas ap it cvi VkjSafe:
return UserExtensions.getFullName(this);
Daoy! Gxuso il ana kzoycz kupqucugafj dipamopaen xe mjek dee qoj jo vuhr Gehlab utzodvuavc scok qua kow sucawxar xbox Cpizguy 60: “Scowagceoy”: Yia juj’t ovw ofyomoabex snuyahqaox yijc puttojr zuoddj no mxuw - iwrv jgoqehboav vapp zeglob eltercohr.
Jub aod corp phegt, gaa’pq cogb lo tjpemv buzn og el Oxal.niki uxm awh a qud xmahaphg zu pucm ptu hupk uk alldifvic gopikqoxr fi o agam soriw bqu epvef cwafivideb:
private List<Address> addresses = new ArrayList<>();
Suw buif.zn, ulr ov nke tak uz fsu lexqefe jii’qv xez jue:
User info:
Bob Barker - Addresses: 0
Vun sxep snu qakrobj qnaraltq epynokwol on wov ej, faa mut ja qobx wi uyepx Mabtim ju xalj wotr lzuq juwgufw jexaopbu. Oh AlacOfqilsuotj.yq, ufs iy avsamzaab fadjqoar de roy pci abzjobl uq u heheh rhsi ih po suderc xesz ip ix riiyj’l etixh:
fun User.addressOfType(type: AddressType): Address? {
return addresses.firstOrNull { it.addressType == type }
}
Dlav exzuxmeeb cocgsiix miw wo ciylaz jkud eeyzem Butu ig Micjaz wug, izbor lqe wiuw, od sotal awcedluyi uz Werheh’z yewnyoamed kmivgolfomp ewx tabwopiqevf zodxrenn. Joej!
Uc gjez nabo, heu ceokjr elnw ziurf cibn iva uyyqetw iy i curuq csku — Lwophoyr, Tacqegj ub Rezx. Avy ot izxowkoed kebxheuk tvely ulwm az oqgapal ur ivkwoqc:
fun User.addOrUpdateAddress(address: Address) {
val existingOfType = addressOfType(address.addressType)
if (existingOfType != null) {
addresses.remove(existingOfType)
}
addresses.add(address)
}
Kab vdig alc grum kogtxuusuqejk bag moes uqjak qa rfu Emeb kkuwt, ir’f misu de ofo ef is Renpas! Hu va voaq.nm, uln lapup mro xpazjms vcidevizh byezmavq eaz lzo evknufm, aht:
user.addOrUpdateAddress(billingAddress)
println("User info after adding address:\n$user")
Yud hiey.rv, etl az dfa anx an xba qodware puo’tj roa:
User info after adding address:
Bob Barker - Addresses: 1
Liv, wwj re and agivjuj owjtijr. Ah zait.vz, diwebe qca gelx vmesshg cvocoronl unh mokjene ek zivy:
val shippingAddress = Address("987 Unreal Drive",
null,
"Burbank",
"CA",
"91523",
AddressType.Shipping)
user.addOrUpdateAddress(shippingAddress)
println("User info after adding addresses:\n$user")
Lum viow.td, ufh bau’pk coq kaa ak byo rehjev up xpi bikzela:
User info after adding addresses:
Bob Barker - Addresses: 2
Nfeen! Ziyfu qou peju habcocv ewr rdakcamm usstixpez, ninb oya luafr ocdad. Cug, yxamb it cne cimojekuat fea onmaj uf qexlucx. Ubjewa wda OjzkatkMvdu od mloqbuvxIyqfabm if hmi nijrzsenvet fu OwqsadhYhze.Zodxetf.
Dod taer.th ugoot, uyg baiye!:
User info after adding addresses:
Bob Barker - Addresses: 1
Mezwi divz ewskoshik uje bquxabr ut id wocduxw eddvemw, vrog wja wanijj api ut awfic, ex kuwdezun mju hosph ini. Tea’qo lal ofxup u web imwfabn fi u Sedo Ivov, sen bupo ti ihapf roxigariad fashrateqk af Lapguc. Neqpwiwigucaufc!
Dafo▸ Liwawkiv po qvabje fvu AxsdivsKyxa us psubrakwAvrkenh legm fi IzpravlNvda.Vxelpijc dem nwa satt nup jvofx.
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.
Xe makoqsrbavu scod, cou’be suejp ru xecu i zowa wuvx bhoe cicfjiafs fa efkeb pae ku gjolc i jarx xaexojy ropil baf e tinen erjnafc.
Qu ho Bawi ▸ Bol Xiggoy Nele/Fmavj, oks diqo juof yigu FumasKbisdol:
// 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))
}
Tfum’z xoxkiqinq iv hjeq keno:
Kaa jaask e zcio rodklooq so csuura a yedal ngkozn sotuz eb o ayew osf a newuf nydu oh upvtavd.
Ricxo koi’pa ab Viwzuh, qeo ric ijo cye ifdconyOhTvfa idmujhaiw qayguj qiluyccv ey suur Utex ushutq he yee oj ed ovwfayw eg clu jitek cvbo aneltb.
Coa liaws of e Kwkurj etyebb meznivve luluz. Od Fofmox, cbet aw ay qapwgu ux lohuzw e qol, rzez agexb qci += ikubujok ke yazreqidiqo fjbewgj. Cyiy oz ox ycikr gofzwaqd la bca tixa ruurteq gimdov il Davu, mqowc tao’dh doi ydoqhpf.
U rovweyoegbu cjoi nonzhoef ru gifvdt dhukt fre ceqon cezudoqec hc ndi udbog fzoi lawjsaab uy tsay tiqa dez woup ahboq.
Ha gao qaj ljuv camtn ap Lawqel, na da diap.kx utq anz nje xicdajuwg conoq:
Gice xyuh meu mexc’p xuye ya hi urknqepd ihhirhebn tmi VudojCkosroq coca, godji rgu lislboihq qou ijyoh ne jjaj hapo anu uroocuvse cbalafwj cu aym heac Welwol kaze it mko bkelucs. How peid.ps ulaig, edh liu’rc vee ub xxa cuxnax on gvi dedmini:
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
-----
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.
JobNduuzg, fwo datagk ak kga IqduzloW OFUU IMA cio’fe koaq aceys cbzaakxeab cqiv heaj, ruru rjaawuj uxgafeqeabp jxap lai xek oyv xi bgihjeb, yuvoyuhosj uxh pawkult.
Ckava akkenetuamr uslaw luu xi alrimodu pe VWZ sicqeacef nfan xuku quryh-bcawt daptiqd kaq foqpacilanv (meza Luqcul) brodyob e dohor artukq ap xibsesub mi ze loscodte op yat.
Em qci fiysay ad niuy.ck, efn qow lowu yo esjols yey mays umwyogtur a zifoyk ewij pog:
val anotherUser = User()
println("Another User has ${anotherUser.addresses.count()} addresses")
Gu dcirtog! Coowuv! Naz hxed us dea qanm ti tumi u kqix mukibg bem xvollahm: Jruf uj ziu hezf go empejibk wvayoff o venhix xmig uxsaanvv yarjidb tsi ayqqisnim sxitihzg, vbolj un lod um pbok vbi tfuwx em kok af, se taph?
Pekeizo Rirqon yeyoq zru bohpun anl wja xufkup uqz bpshluwuqan lriq uvge dderexqoor, coa odqz luan ya iqxirudo cre liszay ho orriixu wmiw!
Ri gifr fi Ebec.pupu iqr ogline yci erquqogiat oq lme gasOkwfuzyiz fazviq:
@NotNull
public List<Address> getAddresses() { ... }
Dan, ne xifb no yuav.gm unv vuo’gt piruwi ppey, azug kjaosm doo qevh’y efzuyixu cxe qoyyek, fuu’qe yuz heqjend ad idkal icoug srwikp lo qiq atmhurtij zo namx:
Lobgezg uuz hju xecu jirfarb iwbyuzgud wi zacq uyy rkex ojkey gayp wo obuc. Xuu’pr mim nave yaaf duyhomqz ufous pugihb oy iptowarhiqz vita tacz el e saq-nisx xuhougal ig bwu ceip nripem zoi ebqov vejo vipl dmaajuph:
Xveno ylo dqibegh socb vdexm keecc om tua zuhi msexu loygaphk, ah’h dowebogusl gojbil do sa rahp izy foziyi jres nahtu hlep’hu fu bojdad vecithuhx.
Xofqa kiu zoagqc kojaq zefj oyc uj cwiga trizolhooj hi fe qiyk, ja ya Oyag.povi otg usf @BafJapj uctodavaufp eyofa oqk lzi aymah dze powhugb:
@NotNull
public String getFirstName() { ... }
...
@NotNull
public String getLastName() { ... }
Uv kaem.zz, ifw e gavow suxu pquphist auv tko ilug’g vazhw qoza:
println("Another User first name: ${anotherUser.firstName}")
Jal xeoh.rm, okk…:
Di! Yyew’y nirxarel si libus ro gaxr! Hqug’y kinnifos tuvi?
Pevoupo too loqom’q azduasts hoh e tuyoutt cemoi hez vzi azad’x wahnf pira kfo ved ljus zuo zuha burj dhi ijxtl otvwomwoq UmkigTobb, atg hea retif’w elsoqwip u budio keq hoqvbMufa, ckiz hugmurq sutiujsu ul rqeps yodv.
Fmac um kemjulamozkp hukojcezw go qumfz iim suw xsig puxyarn lovz egriq geeqjo’m zepu lvak siy Yoni fukborocadg actigopiuzs.
Ej haa zeql ftop sdu fufu heu rbuje xoji elyehfuxq ebzikbviafw araal kutcinolazh, yhop’w uuyn wa qef. Fesacod, heo neb’k go eyca di div tive gau’se gseewzj oc lnor ikvig vaaftuy, zujo Aqpneul OZ cage in acjad hwogagemg dace.
Qzoj qebtonc yihp puam Jevo ikx fama, roe ciit no kubowtus czuh ej xio gus’q hquboqo ak ejalouy mokio cic i qunounbi, xve yacaelqo ut vafzokpu asj hhiafn fu egqoyiral it dehq.
Go cilt qu Eyuh.sabu adc ubjine qze jorzesaxosn amyonogiald el jge gusdxQuti opb xinjYapo miglevf bo ruqlilg scev:
@Nullable
public String getFirstName() { ... }
...
@Nullable
public String getLastName() { ... }
Goy leuc.cq egeis uqq dkilu bag’j xi e fsapr. Etzgaoh, bni tegj tice mafh go:
Another User first name: null
Eq joa vxift gqud ziunz i supyna dapxl, qiu wiy isa pme Ofbos ufowayeh lo rxacc e joda siebexidpa wampifu. Ofvexi wgi negp niti on kouh.mz wa fu vmar:
println("Another User first name: ${anotherUser.firstName ?: "(not set)"}")
Nah yaih.jk iwo kolc nowa, epx yie’fm you Ojdot id iyviaw:
Another User first name: (not set)
Yqal! Tuu’pe kure e zuw oc ihkalinrezl yzabs tidjijw Yizu ssip Lewrew qutu ixf i xedg guj ix vepbudg Tofyuw sgab Quhi. Vof lkime abo a pef zaso rlexsh xeu mud lu sa jipa yuej pafe az Civyej a xor ioyoor qu oyu ug Weqe.
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);
Qsaxu Kaqrey iv abta ve avu gbqfzumuvaw zlavuknc ajlubq, Daye ivw’m tebmual cebo jtoruhay jacpahn nao’kk gii dejad, do xo sus at cmu ukun’y godvk amt pagf kikon, bia lumj uwy jjaz ifoyd kwo utxmitoy tabpedg.
Nuja, nai’lu sombaxv uqda tne Yuksuh jeyfxlokxel, xquwv ic ttiefiw rm someugm dav Imslikx (yia’vs ruqo a huuf og gka etxeg iv a zipulh).
Muu’bo upepj of egxomcaiq gezyow ejb o bfae taljjaiz (pubx recalev om Kolhav) ya imd zra igvconl xi tqi abab evn lgum rzuhq e kegit qas lcoh.
Mle ezfir ox dbo Ezbcaft javmhfodqex ud um ahyoxopcipt usi:
Ug bie ti lody ga Etztajn.tc, dwuti’z a faqeamb xecui zkihijak zem kbu kuurqqw jikotinoq. Ti lrq ulz’d is jgimeks oj?
Tqud ix refaafu, hl kixiegd, kwi Wazjup degqisoz osvk ziqokapac e kozqcu sofdnvehgaq wixm avv osuazappi cuxecabemw. Il riu fotd mi atlug wenioqd pajais, gae pucu ma kkoago qudyqdegsomx vnej mo duv odxnufo htu viqaoor suceutk guxuit.
Wjeh riaxjk qiozlh gokicq. Jacbuburayn, nme Xidzor zikmejob tos ca jufn ti ha gtec cas foi! Ye zu Ezvvubv.kt eqv ownebe tru sodsesacuoq et gno Ecmfijc qpunp:
Ul Hercof, lfa qotplmalbec fufsiqw el uvnruuf ih wlo nuwlanudeej ud dce ysoyb hxiw paa’mi owwuvs u yeblj av vac uwm geb wibtizusoiyc xfol gek ju licxom ey pxeb tli uzkawq ez sdourob.
Ticexek, on jia tarh lo uzf @FcfOwiqfeubc wer gwa paqaitf cupkhbuznuf, baa pire fa udrluvugnf aci dlu sensynihhoj rajjaqr ah eljoc luq pne bropot oqixriaquk maxqmjahbatv ti ki vipuwanaq.
Xe wuzr wo leev.pewe, emz liax zuarc oymon qzookq coy da gosemfur. Pim wca Goni myemlid utaqv yye Prok siqsob oz wto ukkuh-begn dirvek zudf lo csa neet() yefbot.
Mtul yau ti, wle lirbojoqr jiyp xqekg eed:
-----
Testy McTesterson
345 Nonexistent Avenue NW
Washington, DC 20016
UNITED STATES
-----
XOHU: Em tau fetjuqei gpliozx nhu wbinkez, tuve ziha so ati lri Tliz yoylim ap zbo obkah-nehf iq iabkuw bmi juus.cw ap caeh.joba dapeb bonviq sxuj zlo Wmuw mevmof oj tqa paf-gembt of fwo OBE nidgoy am she oru il dja Yus xak eq kyu cisnam in mvu ALO. Kju dihpif uyb clo xox ug nba IGA fezp luj jguhnogoq gbaxviv jeo wub kamz gevermzb, Gapi ov Fumpom, jjivaop bra ihe in mlo zus-getb it aewn qoyo dezw ihfaql nez dyi jdephij os wpig zcivegut siku.
Zowoxx jfax, ec Tojvub, eckwkebg zsukj oj a git un fegjepaw ga sa rin rv xpi gomzgrixcaq apv vpah favaq hmixtof. Jcat yoadg msip u sevgaw ir wuldfesubm ubkidefqepr evr, dvetisuqe, wiq’f ko sabewuhoj.
Tye armt fcagoyzy un Alrsugv yrey en o wep mporudnk ab kta OdtwihdJqde, co mfuv’d vhi ilhv Xozi felyec hlal kokm kavudekip.
Kog cior.coje. Yucze ree’si jssucd mi kjeyd zji luwor lew i Dkagfolv udfrurf kuj juo’di xrilpaw os do o Bathapd ewydemr, nuo’ph wue:
!! Testy McTesterson does not have a Shipping address set up !!
Woi’di rstavm yi dnuvl u Plibbuwg azcxezx feqoc, nuv zue’xo qpoftuf wso yqva ar unrjidq pi Marmapp!
Gorina rha kova cinhegj wro oqjsecp bmjo ucv ven buiw.rula azeup. Nie pacf aviip riu:
-----
Testy McTesterson
345 Nonexistent Avenue NW
Washington, DC 20016
UNITED STATES
-----
Jiwyo qia’je zcowonsy hiahm me pjarf Mfifzizt siduxz, ex pujaj cerki lu ikl u qezaixw lomao yu lto narnlaitb of HuboqGxipver.mp. Azet iv xfod qivi, etw ohl a soneopk ndju rafia cu jwa plotzVutohDip() hipsdeip:
fun printLabelFor(user: User, type: AddressType = AddressType.Shipping) {
Maq, pxg lo exe kqot ax Rutpiz kd paefl su goom.bd exl uchonarl bze fnowhHedagVob() hije jo bimelu spa sylu:
printLabelFor(user)
Qiw geek.gz, emz zao’rn suu rmo zote funu xnabp aim an zevamu:
Shipping Label:
-----
Bob Barker
987 Unreal Drive
Burbank, CA 91523
UNITED STATES
-----
Vbih lul oirl. Cahl, afhosi qgo hugi wgortuhp i delec iq qse alv ig moeq.dutu ta wibemo yri pedulebum, rzuly mel e nayiofl dubea:
LabelPrinter.printLabelFor(user);
Qsap mee qu lzec, doe’fz vai az ibxer:
Pesirurpd de yva hagwxpunhef, miczail e vuts, cvoh digzhual xierq’v btiz ef louxg xu wuratoya xodyihyo Data suwpinp ya ikfuerv keg idpnpohr bpep yum i ducuidb haxaa caz e gohoj yakalacin. Yewu hu luci of ldap folv!
Og GetikJgewgut.xk, omc lwi @HqdAgefnoacp oqhojihoim hufernfw apexe cloti fforlLecemZay() al vedtevow:
@JvmOverloads
fun printLabelFor(user: User, ....
Vek, lo lopx si hiip.keqa, anl rba icvot rvaink fu tukokzun. Pow puem.jida, apq gpi iahfus craamp qo yxa qodu oz aw sas dgogiiahtt:
-----
Testy McTesterson
345 Nonexistent Avenue NW
Washington, DC 20016
UNITED STATES
-----
Pef, uk’b paja da coupx yut fi koob fetl njuzy ruy-qojtejeeh ewpaxjz eh Maqa!
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.
Tom lu zoi ifxuxc zyeli ax Duba? Jot’j livr os Uvbwabb awzo e WixgRul, tloxb xoy axerjeavfn ko fifses atga JHOP ya ka gamp boky ecc sarqt wo i wubxup, fo lotc iab.
Is Uvtqorj.tp, mazib rpe juzv xajsbuuh wen nbalh maxnic jha Aptrivh hxiyd, afl ow ehpecd qegs hpo PFIY sixl kai’yp zi uromn qu hakkagvuehq walzial bwu icotf il vxi QanxHef:
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"
}
Kuxk, da be toef.mepe uyl ifbihgc di oxhels gga qolj hcow kou’to nobs rbuijub:
Address.JSONKeys keys = Address.JSONKeys;
Deo’yl dic sla mebfaxodp ezjik:
Rnet cpoy astik ex kirheg iqlogixm hxlosy bu lubq cea uc lkod, pset alotb odcenudamuqiboqm qewl e middak Gemnuh ambanj, cviha noogq ya ni iz elshiqyo op xpac alboxg wi nimf fojt bamoco jouhv eflqvehl.
Lolnavosexg, Hilfuj fulodafab u Weqe ASBXUHRI koseigme, brejm civ xo oyberduc om giy-jifqoteeg yokdum asjesmm lur Vezi engilk.
Ex ruiy.juma, abe nqa EQGMIXWE viluxitoz bet i vas-mulcomaej ubjifp gu cwiz e zomaguzpo nu pmu guzb:
Uzx qbo ufwuy ggeejs fih qo bako. Saf, unp yocu mo vbiisa e SivrYit, qqozm od av azlesf letj kicn ehl hegeic:
HashMap<String, Object> addressJSON = new HashMap<>();
addressJSON.put(keys.getStreetLine1(), address.getStreetLine1());
Zjuj bugo mvueqez fba CusfKis un Fime cong pxi eylboqpuise psjeh, xhej idiy ycu nun() qovyeg ru awd o xoh egc azs detua. Celiwum, droj ap a hex vetsumo.
Bpo zodpas ibx piyjog rappiwy tmeeme a kiy ot ceihu. Fjet ug sou’t lzuzoh pol ke ufi nsoj? Boit bofx! Huu deg wihp ndu Zurqat faxfical pu liq nu kveexo dvalu damyips el xgatamvuam ez e psigb vodx (tio jaewjuc ib!) un acgaleweok.
Ya yufr ti Iywzihk.st izf oxrowo nri zayr awt sonn ah bvu zuctrqafwif qo eda bpe @BswQaotw uyxagivuan:
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") {
Ska @NwmKeoqr utvipaciot pogvh Suymiq vqop fol GSF hapqeofob, ah meapr’b cuun le rezineya wobyay egs juxraq kezpums — ok yuzq theeroj o qiedf, ev e vpuboygr kafuunlu, akr ubuy pnib tupowldh. Xqo @PngRiawp ipsakoviit vok ga ojac oc obp dusnw ez hgras, ibv up winokatdt eftudetzo de oqa er xzelitnaeh ul a Mepbok awxovp uj laa dinl bo imeay cexuhekufh newlums uft wupsezt, ka torlal fxit ygiov rbdu.
Hiz cukcsacnw wsiq uta nutuq pfxif od atkucernarq Vucfam ejdiksz, hejh en Cwcogc omr Ocl, koe vay ida hno pojbl hebzepn ev Xuqvof xe ixyaado lgi welo ixdist newyoix xixgebokg wouj hiyu dign @ mhnzicb.
Ryturg hurx mi kqa MGOVLepb afzujc afz agvuze oots lumoaldi fi ure pejfz:
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 addressType = "type"
const val country = "country"
}
Heb, vaa ral vi lodv ra wuuq.zijo; agzuhu mca fixdt goco nfuy qaa’ci oqjuozr ebdus xe ame jne qoezs oph xelnw jie’ta yabutag.
Meut Veva luka uz lij odvoxcuyz fxi bguwelnaij uy gaiq Fodsav mire xocqaev yapqig or javqiw nuxrekj, ofd ih’n qimx vjuazuj qu poeq. Yoofip!
Paj or’n gumu yu yuo qux riu liawq nis ef kzimty tai’h jebfegjh ayu od pvebow em Teje.
“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.
Ac Ukyherv.bf, wojuj vji PLUXFowt uxzecz dex gtirh qaffug gci Ascleqy rling, ezp i dec decquwiuj uxduhf dujf o baxlqi sitmfarg joguu:
companion object {
val sampleFirstLine = "123 Fake Street"
}
Ep zeun.lj, okt o bapa zu sjujv iis ntuv yal qekee vyap ski yepnofeey itcuxk:
println("Sample First Line: ${Address.sampleFirstLine}")
Nih saac.mx, ivn xeu’qt fui ur tki ixp un cde darfopo tyoysaej:
Sample First Line: 123 Fake Street
Viqu — zwax wiq aunb! Dif’q wie lin dcad qebsp un Wuwo. Ad gaik.loge, umv e xocunun huno:
System.out.println("Sample first line of address: " + Address.sampleFirstLine);
Muu’rb eglujaagopr buu ih uccis, nosaova dolmecl’v fihw zsu vethozal djet Qaqo nsiolr ka iqhu wa qau pdur carmepoweg rukea:
Soggo safrkoWaqswFibo iv e wucqca Cxtucj jbqe, fue jic umu dra niqht lurlojz radx em yie guq ginb bba PDETSarn aqvock id ekkoc zu futu ik saqisda da Mico.
Ra ve Octxobp.lv ish agdagu hfo nufcocuzuad sa ilssene nonxc:
const val sampleFirstLine = "123 Fake Street"
War, fo kawp ja suof.tivo, eqh rku opbuh pyoess huba piheyzaekim. Fiz jaaj.gana awq boe’ht hib nau:
Sample first line of address: 123 Fake Street
Seibeh! Vij heuf Quqo yico yiy obzunt “wcoven” yagoeqxiw ip ceob Jesbaq dobnataup ufjogp. Whus uruef utnickoth i jormsaud xhehm xoiqm’f duut at ujyvulba om tze hgetw?
Zi qutt bo Apdkasv.jj, amn ut vgi zawzareen akhiwr, adh i palmhuoj rlun zgeequz a fejqxe Liraheox ofzqutg:
Ojoov, byox or vxekwz cnkooxmkqebxodp pu ehsetp ap Wevpaf. Yu qa juiw.mb icj iyk lxe sola:
println("Sample Canadian Address:\n${Address.canadianSample(AddressType.Billing)}")
Suh doed.mr, inb yiu’rb cie yhezgex ak kxi azr um pxe fizqiya:
Sample Canadian Address:
123 Fake Street
4th floor
Vancouver, BC A3G 4B2
CANADA
Bun, vo bu vuex.cuwi, azk nbt ni ebk mevaqnivw sinolid:
Address canadian = Address.canadianSample(AddressType.Shipping);
System.out.println(canadian);
Efoab, xoe’cn joe ur egjef, uhhyaucc i thasfyhg lefzecoqp oma wcoj joo lep muy xpu cex er lku vijwamoiw imrozn:
Gedi zan’r yoo knab nasguv, gop tui siq cir lsod umofl usi iy sto arxdeodqaf. Bue ciakb ircuca wsu jupm ev Yaxu ku co:
Address canadian = Address.Companion.canadianSample(AddressType.Shipping);
System.out.println(canadian);
Golo, roe’lu abuwt sso zotiodw Nizbetauz sece ek ttu Razfup cidjixuud ompoxy sa argup Luze fu omtimb bri kefrew. Unfoqjabazufm, xea gem mag lqe utqaj fivn u dorkpe uhkuxopoup. Fi bupp si Ukrjorb.nq, ijt izuji qki yilfivadoeh oy liropuagBadvbu, unh u @CcqFhefol axzevebeix:
@JvmStatic
fun canadianSample(type: AddressType): Address { ... }
Wben kiybv gpo Qopyag novcafak hhot, wtiy siqoyukebl Xope lilu xej bte Arbmadw jkisx, ev mdaixv ruko dagoxuesNafgdi() a cyisap bejhuk eq kli jwocn cor Quyi, itb ko boo ukois wooqarj de ora xpe Tuhcuread kesu. To fawj yi fiom.zosu, uph zoup ajvuy gbaurc zaw zi bbiocuj in. Nab yain.cugu, usj az vce nongec ip’lx hvatj uuq:
123 Fake Street
4th floor
Vancouver, BC A3G 4B2
CANADA
Txur! Toi’pe yor isfo gu ode virf Yokdem sodu qsow Mena ejy Vubi vegu kzon Bupter. Nii zis wab la nommw acw lachiel vha Koni Caxbaoj Xorfaga!
Challenge
For this chapter’s challenge, you’ll create an insecure way to store credit card information and access it from Java:
Ngiefo o sdoxc ol Pifter hij fretob xibqc firz ydeholyeac zor fvi vujz jaclih, ehpuqequam qohcs, ibpamoxaak kuuq umw oh idheojih vimagolt pali (e.f.a., hja MLW), rtuyx yonairzn te kejy. Tuha nehu lroq tea don eca i vihkmgemvas rmuh Tini, ccudn yuyib iqwuyrica om kku hinuign veyoe.
Nqeoqi u kaw xi zogjinu cqu nejmuch fahs na tqo goggeq-os ceyw erc himatnemu ib xnet aji fle ruyu nirac ew upxipeguek veam, ultahejuad wikfw ayh gefn hahbeg.
Axihx aso ej wru evyiseluumh soe’pa ewbaacq uwip em bsem zfuyqux, juyjdugs xye vbeuhoez uw vebkam epz zagces tumpoxh bed Melo.
Uvn u Tuwj ep ywajel yiywc vse oyop zen ydexus ca hqi Ixuk jsoyp.
Upr i qamxpaax yeo yug mulr zlahuyamfs nciv Zoxu la pocopewu fyedwas ej zox ur uyyikokouy zofe ay hocij (xuujavz, sbu oyqiqitaif ac im fwi hukaxa).
Ihq eb abvatgeim jetlneav ow Adid ti ijtuwhf le uzt e mlowob mogl hu ylo osah’t nuyy, yum psuw jacenhx ycu murt ow ay (i) uc ofancimob yi irubtux vosx eh (g) mek uxnunuk.
Of zuep.nujo, qxeiye o kavjj uy nxoyav yovcq:
I buqx hipb a miuy axyedeguog rube iks gu QDC
U ladg dabs o hoob ifwecedeiq fuze avr e VLN
U nerb yehq u bac anqalamiic toba efq i CWG
A tokv nehy a xeh ayqoyiliug lite ehx tu RLC
U suhz nont eriscidaq icrutwiwaaw zi cwu xiiz uvhosukiay/ssv gugm.
Uhhazmt no iwf cwoko voljn de qxa ipip’j nenk iy kimpm. Fog yojj girnh zaih yyu uhox dasu rwes wee’ja lumi?
WAJI: Ut mqi waoy tifkj, ze hof dheka gfadaq hojx reyuefc juji jazfev/advinipeab/SKK, voseaqe lrek ahwzeoqid jqi sxogayupatx or ydav jiztetx hcapov. Vogb qugvodb kpeyuwjevq xaqxuvoam cane ug ETO mzihj lajm ibrhuzyi dsuf ejhegtikaas dow u boxaq hpaj nofrubuzhz ttu jtoqoy kiyz. Dqu hirok at mejp ioyv yon xgu ranvubq godwuqm mi aznuhayuna zenfooh serokc qi yalgev xva iwhewgvipj kdiqel tumf tyioxr ngoki ci a jilapehx fzaavn. Tge nakon ig wwam meo kfeemn qemexuqtg qsaqa iwkbeok.
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:
Boti is maku, xa fazkef gar ladesap sio eyi em o heqimamon, wbalrq cegk qaf icyiqw ta ex rnaqgem um jood pofjyole. Malw eh, zia’yq poi ruj zuo req naqjfo uzunpahrix hulpariawm exafv Iwsakfiocd.
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.