CINXE.COM

(Deprecated) Converting to Kotlin  |  Android Developers

<!doctype html> <html lang="en" dir="ltr"> <head> <meta name="google-signin-client-id" content="721724668570-nbkv1cfusk7kk4eni4pjvepaus73b13t.apps.googleusercontent.com"> <meta name="google-signin-scope" content="profile email https://www.googleapis.com/auth/developerprofiles https://www.googleapis.com/auth/developerprofiles.award"> <meta property="og:site_name" content="Android Developers"> <meta property="og:type" content="website"><meta name="theme-color" content="#34a853"><meta charset="utf-8"> <meta content="IE=Edge" http-equiv="X-UA-Compatible"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="manifest" href="/_pwa/android/manifest.json" crossorigin="use-credentials"> <link rel="preconnect" href="//www.gstatic.com" crossorigin> <link rel="preconnect" href="//fonts.gstatic.com" crossorigin> <link rel="preconnect" href="//fonts.googleapis.com" crossorigin> <link rel="preconnect" href="//apis.google.com" crossorigin> <link rel="preconnect" href="//www.google-analytics.com" crossorigin><link rel="stylesheet" href="//fonts.googleapis.com/css?family=Google+Sans:400,500,600,700|Google+Sans+Text:400,400italic,500,500italic,600,600italic,700,700italic|Roboto+Mono:400,500,700&display=swap"> <link rel="stylesheet" href="//fonts.googleapis.com/css2?family=Material+Icons&family=Material+Symbols+Outlined&display=block"><link rel="stylesheet" href="https://www.gstatic.com/devrel-devsite/prod/v38a693baeb774512feb42f10aac8f755d8791ed41119b5be7a531f8e16f8279f/android/css/app.css"> <link rel="stylesheet" href="https://www.gstatic.com/devrel-devsite/prod/v38a693baeb774512feb42f10aac8f755d8791ed41119b5be7a531f8e16f8279f/android/css/dark-theme.css" disabled> <link rel="shortcut icon" href="https://www.gstatic.com/devrel-devsite/prod/v38a693baeb774512feb42f10aac8f755d8791ed41119b5be7a531f8e16f8279f/android/images/favicon.svg"> <link rel="apple-touch-icon" href="https://www.gstatic.com/devrel-devsite/prod/v38a693baeb774512feb42f10aac8f755d8791ed41119b5be7a531f8e16f8279f/android/images/touchicon-180.png"><link rel="canonical" href="https://developer.android.com/codelabs/java-to-kotlin"><link rel="search" type="application/opensearchdescription+xml" title="Android Developers" href="https://developer.android.com/s/opensearch.xml"> <link rel="alternate" hreflang="en" href="https://developer.android.com/codelabs/java-to-kotlin" /><link rel="alternate" hreflang="x-default" href="https://developer.android.com/codelabs/java-to-kotlin" /><link rel="alternate" hreflang="ar" href="https://developer.android.com/codelabs/java-to-kotlin?hl=ar" /><link rel="alternate" hreflang="bn" href="https://developer.android.com/codelabs/java-to-kotlin?hl=bn" /><link rel="alternate" hreflang="zh-Hans" href="https://developer.android.com/codelabs/java-to-kotlin?hl=zh-cn" /><link rel="alternate" hreflang="zh-Hant" href="https://developer.android.com/codelabs/java-to-kotlin?hl=zh-tw" /><link rel="alternate" hreflang="fa" href="https://developer.android.com/codelabs/java-to-kotlin?hl=fa" /><link rel="alternate" hreflang="fr" href="https://developer.android.com/codelabs/java-to-kotlin?hl=fr" /><link rel="alternate" hreflang="de" href="https://developer.android.com/codelabs/java-to-kotlin?hl=de" /><link rel="alternate" hreflang="he" href="https://developer.android.com/codelabs/java-to-kotlin?hl=he" /><link rel="alternate" hreflang="hi" href="https://developer.android.com/codelabs/java-to-kotlin?hl=hi" /><link rel="alternate" hreflang="id" href="https://developer.android.com/codelabs/java-to-kotlin?hl=id" /><link rel="alternate" hreflang="it" href="https://developer.android.com/codelabs/java-to-kotlin?hl=it" /><link rel="alternate" hreflang="ja" href="https://developer.android.com/codelabs/java-to-kotlin?hl=ja" /><link rel="alternate" hreflang="ko" href="https://developer.android.com/codelabs/java-to-kotlin?hl=ko" /><link rel="alternate" hreflang="pl" href="https://developer.android.com/codelabs/java-to-kotlin?hl=pl" /><link rel="alternate" hreflang="pt-BR" href="https://developer.android.com/codelabs/java-to-kotlin?hl=pt-br" /><link rel="alternate" hreflang="ru" href="https://developer.android.com/codelabs/java-to-kotlin?hl=ru" /><link rel="alternate" hreflang="es-419" href="https://developer.android.com/codelabs/java-to-kotlin?hl=es-419" /><link rel="alternate" hreflang="th" href="https://developer.android.com/codelabs/java-to-kotlin?hl=th" /><link rel="alternate" hreflang="tr" href="https://developer.android.com/codelabs/java-to-kotlin?hl=tr" /><link rel="alternate" hreflang="vi" href="https://developer.android.com/codelabs/java-to-kotlin?hl=vi" /><title>(Deprecated) Converting to Kotlin &nbsp;|&nbsp; Android Developers</title> <meta property="og:title" content="(Deprecated) Converting to Kotlin &nbsp;|&nbsp; Android Developers"><meta name="description" content="In this codelab, you’ll learn how to convert your Java code to Kotlin"> <meta property="og:description" content="In this codelab, you’ll learn how to convert your Java code to Kotlin"><meta property="og:url" content="https://developer.android.com/codelabs/java-to-kotlin"><meta property="og:locale" content="en"> <link rel="stylesheet" href="/extras.css"></head> <body class="" template="codelab" theme="android-theme" type="codelab" appearance layout="docs" display-toc pending> <devsite-progress type="indeterminate" id="app-progress"></devsite-progress> <a href="#main-content" class="skip-link button"> Skip to main content </a> <section class="devsite-wrapper"> <devsite-cookie-notification-bar></devsite-cookie-notification-bar><devsite-header role="banner"> <div class="devsite-header--inner nocontent"> <div class="devsite-top-logo-row-wrapper-wrapper"> <div class="devsite-top-logo-row-wrapper"> <div class="devsite-top-logo-row"> <button type="button" id="devsite-hamburger-menu" class="devsite-header-icon-button button-flat material-icons gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Navigation menu button" visually-hidden aria-label="Open menu"> </button> <div class="devsite-product-name-wrapper"> <a href="/" class="devsite-site-logo-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Site logo" track-type="globalNav" track-name="androidDevelopers" track-metadata-position="nav" track-metadata-eventDetail="nav"> <picture> <source srcset="https://www.gstatic.com/devrel-devsite/prod/v38a693baeb774512feb42f10aac8f755d8791ed41119b5be7a531f8e16f8279f/android/images/lockup-dark-theme.svg" media="(prefers-color-scheme: dark)" class="devsite-dark-theme" alt="Android Developers"> <img src="https://www.gstatic.com/devrel-devsite/prod/v38a693baeb774512feb42f10aac8f755d8791ed41119b5be7a531f8e16f8279f/android/images/lockup.svg" class="devsite-site-logo" alt="Android Developers"> </picture> </a> </div> <div class="devsite-top-logo-row-middle"> <div class="devsite-header-upper-tabs"> </div> <devsite-search enable-signin enable-search enable-suggestions enable-query-completion tenant-name="Android Developers" > <form class="devsite-search-form" action="https://developer.android.com/s/results" method="GET"> <div class="devsite-search-container"> <button type="button" search-open class="devsite-search-button devsite-header-icon-button button-flat material-icons" aria-label="Open search"></button> <div class="devsite-searchbox"> <input aria-activedescendant="" aria-autocomplete="list" aria-label="Search" aria-expanded="false" aria-haspopup="listbox" autocomplete="off" class="devsite-search-field devsite-search-query" name="q" placeholder="Search" role="combobox" type="text" value="" > <div class="devsite-search-image material-icons" aria-hidden="true"> </div> <div class="devsite-search-shortcut-icon-container" aria-hidden="true"> <kbd class="devsite-search-shortcut-icon">/</kbd> </div> </div> </div> </form> <button type="button" search-close class="devsite-search-button devsite-header-icon-button button-flat material-icons" aria-label="Close search"></button> </devsite-search> </div> <devsite-appearance-selector></devsite-appearance-selector> <devsite-language-selector> <ul role="presentation"> <li role="presentation"> <a role="menuitem" lang="en" >English</a> </li> <li role="presentation"> <a role="menuitem" lang="de" >Deutsch</a> </li> <li role="presentation"> <a role="menuitem" lang="es_419" >Español – América Latina</a> </li> <li role="presentation"> <a role="menuitem" lang="fr" >Français</a> </li> <li role="presentation"> <a role="menuitem" lang="id" >Indonesia</a> </li> <li role="presentation"> <a role="menuitem" lang="it" >Italiano</a> </li> <li role="presentation"> <a role="menuitem" lang="pl" >Polski</a> </li> <li role="presentation"> <a role="menuitem" lang="pt_br" >Português – Brasil</a> </li> <li role="presentation"> <a role="menuitem" lang="vi" >Tiếng Việt</a> </li> <li role="presentation"> <a role="menuitem" lang="tr" >Türkçe</a> </li> <li role="presentation"> <a role="menuitem" lang="ru" >Русский</a> </li> <li role="presentation"> <a role="menuitem" lang="he" >עברית</a> </li> <li role="presentation"> <a role="menuitem" lang="ar" >العربيّة</a> </li> <li role="presentation"> <a role="menuitem" lang="fa" >فارسی</a> </li> <li role="presentation"> <a role="menuitem" lang="hi" >हिंदी</a> </li> <li role="presentation"> <a role="menuitem" lang="bn" >বাংলা</a> </li> <li role="presentation"> <a role="menuitem" lang="th" >ภาษาไทย</a> </li> <li role="presentation"> <a role="menuitem" lang="zh_cn" >中文 – 简体</a> </li> <li role="presentation"> <a role="menuitem" lang="zh_tw" >中文 – 繁體</a> </li> <li role="presentation"> <a role="menuitem" lang="ja" >日本語</a> </li> <li role="presentation"> <a role="menuitem" lang="ko" >한국어</a> </li> </ul> </devsite-language-selector> <a class="devsite-header-link devsite-top-button button gc-analytics-event" href="https://developer.android.com/studio" data-category="Site-Wide Custom Events" data-label="Site header link" > Android Studio </a> <devsite-user enable-profiles id="devsite-user"> <span class="button devsite-top-button" aria-hidden="true" visually-hidden>Sign in</span> </devsite-user> </div> </div> </div> </div> </devsite-header> <devsite-book-nav scrollbars hidden> <div class="devsite-book-nav-filter" hidden> <span class="filter-list-icon material-icons" aria-hidden="true"></span> <input type="text" placeholder="Filter" aria-label="Type to filter" role="searchbox"> <span class="filter-clear-button hidden" data-title="Clear filter" aria-label="Clear filter" role="button" tabindex="0"></span> </div> <nav class="devsite-book-nav devsite-nav nocontent" aria-label="Side menu"> <div class="devsite-mobile-header"> <button type="button" id="devsite-close-nav" class="devsite-header-icon-button button-flat material-icons gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Close navigation" aria-label="Close navigation"> </button> <div class="devsite-product-name-wrapper"> <a href="/" class="devsite-site-logo-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Site logo" track-type="globalNav" track-name="androidDevelopers" track-metadata-position="nav" track-metadata-eventDetail="nav"> <picture> <source srcset="https://www.gstatic.com/devrel-devsite/prod/v38a693baeb774512feb42f10aac8f755d8791ed41119b5be7a531f8e16f8279f/android/images/lockup-dark-theme.svg" media="(prefers-color-scheme: dark)" class="devsite-dark-theme" alt="Android Developers"> <img src="https://www.gstatic.com/devrel-devsite/prod/v38a693baeb774512feb42f10aac8f755d8791ed41119b5be7a531f8e16f8279f/android/images/lockup.svg" class="devsite-site-logo" alt="Android Developers"> </picture> </a> </div> </div> <div class="devsite-book-nav-wrapper"> <div class="devsite-mobile-nav-top"> <ul class="devsite-nav-list"> <li class="devsite-nav-item"> <a href="/studio" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Android Studio" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Android Studio </span> </a> </li> </ul> </div> </div> </nav> </devsite-book-nav> <section id="gc-wrapper"> <main role="main" id="main-content" class="devsite-main-content" has-sidebar > <div class="devsite-sidebar"> <div class="devsite-sidebar-content"> <devsite-toc class="devsite-nav" role="navigation" aria-label="On this page" depth="1" scrollbars ></devsite-toc> <devsite-recommendations-sidebar class="nocontent devsite-nav"> </devsite-recommendations-sidebar> </div> </div> <devsite-content> <article class="devsite-article"><style> body { transition: opacity ease-in 0.2s; } body[unresolved] { opacity: 0; display: block; overflow: hidden; position: relative; } </style> <div class="devsite-article-meta nocontent" role="navigation"> <ul class="devsite-breadcrumb-list" > </ul> </div> <h1 class="devsite-page-title" tabindex="-1"> (Deprecated) Converting to Kotlin </h1> <devsite-feature-tooltip ack-key="AckCollectionsBookmarkTooltipDismiss" analytics-category="Site-Wide Custom Events" analytics-action-show="Callout Profile displayed" analytics-action-close="Callout Profile dismissed" analytics-label="Create Collection Callout" class="devsite-page-bookmark-tooltip nocontent" dismiss-button="true" id="devsite-collections-dropdown" dismiss-button-text="Dismiss" close-button-text="Got it"> <devsite-bookmark></devsite-bookmark> <span slot="popout-heading"> Stay organized with collections </span> <span slot="popout-contents"> Save and categorize content based on your preferences. </span> </devsite-feature-tooltip> <devsite-toc class="devsite-nav" depth="1" devsite-toc-embedded > </devsite-toc> <div class="devsite-article-body clearfix "> <google-codelab-analytics gaid="UA-49880327-14" ga4id="G-JTFZSJVVVZ"></google-codelab-analytics> <google-codelab codelab-gaid="" codelab-ga4id="" doc-id="1d5jO0GE8bbZ6HVOuNzsrFfSHc686_s4RFkLJol0226s" id="java-to-kotlin" title="(Deprecated) Converting to Kotlin" no-tooltip="" environment="web" category="" feedback-link="" layout="paginated" > <google-codelab-step label="Welcome!" duration="5" step="0"> <google-codelab-about codelab-title="(Deprecated) Converting to Kotlin" last-updated="2024-12-09T14:34:29Z" duration="53"> </google-codelab-about> <h2 class="step-title" id="0" data-text="Welcome!" tabindex="-1"> 1. Welcome! </h2> <aside class="warning"><p> This codelab is deprecated and it will be removed soon.</p> </aside> <aside class="special"><p>[This codelab is also available in <a href="https://developer.android.com/codelabs/java-to-kotlin-zh/#0" target="_blank">Chinese</a> and <a href="https://developer.android.com/codelabs/java-to-kotlin-pt-br/#0" target="_blank">Brazilian Portuguese</a>]</p> </aside> <p>In this codelab, you&#39;ll learn how to convert your code from Java to Kotlin. You&#39;ll also learn what the Kotlin language conventions are and how to ensure that the code you&#39;re writing follows them.</p> <p>This codelab is suited to any developer that uses Java who is considering migrating their project to Kotlin. We&#39;ll start with a couple of Java classes that you&#39;ll convert to Kotlin using the IDE. Then we&#39;ll take a look at the converted code and see how we can improve it by making it more <a href="https://en.wikipedia.org/wiki/Programming_idiom" target="_blank">idiomatic</a> and avoid common pitfalls.</p> <h2 class="checklist" is-upgraded id="what-youll-learn" data-text="What you'll learn" tabindex="-1">What you'll learn</h2> <p>You will learn how to convert Java to Kotlin. In doing so you will learn the following Kotlin language features and concepts:</p> <ul> <li>Handling nullability</li> <li>Implementing singletons</li> <li>Data classes</li> <li>Handling strings</li> <li>Elvis operator</li> <li>Destructuring</li> <li>Properties and backing properties</li> <li>Default arguments and named parameters</li> <li>Working with collections</li> <li>Extension functions</li> <li>Top-level functions and parameters</li> <li><code translate="no" dir="ltr">let</code>, <code translate="no" dir="ltr">apply</code>, <code translate="no" dir="ltr">with</code>, and <code translate="no" dir="ltr">run</code> keywords</li> </ul> <h2 is-upgraded id="assumptions" data-text="Assumptions" tabindex="-1"><strong>Assumptions</strong></h2> <p>You should already be familiar with Java.</p> <h2 is-upgraded id="what-youll-need" data-text="What you'll need" tabindex="-1">What you'll need</h2> <ul> <li><a href="https://developer.android.com/studio/" target="_blank">Android Studio Bumblebee</a> or <a href="https://www.jetbrains.com/idea/" target="_blank">IntelliJ IDEA</a></li> </ul> <aside class="warning"><p>Note that the auto-converter in future versions of Android Studio might create slightly different results.</p> </aside> </google-codelab-step> <google-codelab-step label="Getting set up" duration="2" step="1"> <h2 class="step-title" id="1" data-text="Getting set up" tabindex="-1"> 2. Getting set up </h2> <h2 is-upgraded id="create-a-new-project" data-text="Create a new project" tabindex="-1"><strong>Create a new project</strong></h2> <p>If you&#39;re using IntelliJ IDEA, create a new Java project with Kotlin/JVM.</p> <p>If you&#39;re using Android Studio, create a new project with the <em>No Activity</em> template. Choose <em>Kotlin</em> as the project language. Minimum SDK can be of any value, it will not affect the outcome.</p> <h2 is-upgraded id="the-code" data-text="The code" tabindex="-1"><strong>The code</strong></h2> <p>We&#39;ll create a <code translate="no" dir="ltr">User</code> model object and a <code translate="no" dir="ltr">Repository</code> singleton class that works with <code translate="no" dir="ltr">User</code> objects and exposes lists of users and formatted user names.</p> <p>Create a new file called <code translate="no" dir="ltr">User.java</code> under app/java/&lt;<em>yourpackagename</em>&gt; and paste in the following code:</p> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="Transact-SQL"><code translate="no" dir="ltr"><span class="devsite-syntax-k">public</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">class</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">User</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-err">{</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-nv">@Nullable</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">private</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">String</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">firstName</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-nv">@Nullable</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">private</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">String</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">lastName</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">public</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">User</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">String</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">firstName</span><span class="devsite-syntax-p">,</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">String</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">lastName</span><span class="devsite-syntax-p">)</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-err">{</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">this</span><span class="devsite-syntax-p">.</span><span class="devsite-syntax-n">firstName</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">=</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">firstName</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">this</span><span class="devsite-syntax-p">.</span><span class="devsite-syntax-n">lastName</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">=</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">lastName</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-err">}</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">public</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">String</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">getFirstName</span><span class="devsite-syntax-p">()</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-err">{</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">return</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">firstName</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-err">}</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">public</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">void</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">setFirstName</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">String</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">firstName</span><span class="devsite-syntax-p">)</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-err">{</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">this</span><span class="devsite-syntax-p">.</span><span class="devsite-syntax-n">firstName</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">=</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">firstName</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-err">}</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">public</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">String</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">getLastName</span><span class="devsite-syntax-p">()</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-err">{</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">return</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">lastName</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-err">}</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">public</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">void</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">setLastName</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">String</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">lastName</span><span class="devsite-syntax-p">)</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-err">{</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">this</span><span class="devsite-syntax-p">.</span><span class="devsite-syntax-n">lastName</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">=</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">lastName</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-err">}</span> <span class="devsite-syntax-err">}</span> </code></pre></devsite-code> <p>You&#39;ll notice your IDE is telling you <code translate="no" dir="ltr">@Nullable</code> is not defined. So import <code translate="no" dir="ltr">androidx.annotation.Nullable</code> if you use Android Studio, or <code translate="no" dir="ltr">org.jetbrains.annotations.Nullable</code> if you&#39;re using IntelliJ.</p> <p>Create a new file called <code translate="no" dir="ltr">Repository.java</code> and paste in the following code:</p> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="Python"><code translate="no" dir="ltr"><span class="devsite-syntax-kn">import</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nn">java.util.ArrayList</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-kn">import</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nn">java.util.List</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-n">public</span> <span class="devsite-syntax-k">class</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nc">Repository</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-n">private</span> <span class="devsite-syntax-n">static</span> <span class="devsite-syntax-n">Repository</span> <span class="devsite-syntax-n">INSTANCE</span> <span class="devsite-syntax-o">=</span> <span class="devsite-syntax-n">null</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-n">private</span> <span class="devsite-syntax-n">List&lt;User&gt;</span> <span class="devsite-syntax-n">users</span> <span class="devsite-syntax-o">=</span> <span class="devsite-syntax-n">null</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-n">public</span> <span class="devsite-syntax-n">static</span> <span class="devsite-syntax-n">Repository</span> <span class="devsite-syntax-n">getInstance</span><span class="devsite-syntax-p">()</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">if</span> <span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">INSTANCE</span> <span class="devsite-syntax-o">==</span> <span class="devsite-syntax-n">null</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-n">synchronized</span> <span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">Repository</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">class</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">if</span> <span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">INSTANCE</span> <span class="devsite-syntax-o">==</span> <span class="devsite-syntax-n">null</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-n">INSTANCE</span> <span class="devsite-syntax-o">=</span> <span class="devsite-syntax-n">new</span> <span class="devsite-syntax-n">Repository</span><span class="devsite-syntax-p">();</span> <span class="devsite-syntax-p">}</span> <span class="devsite-syntax-p">}</span> <span class="devsite-syntax-p">}</span> <span class="devsite-syntax-k">return</span> <span class="devsite-syntax-n">INSTANCE</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-p">}</span> <span class="devsite-syntax-o">//</span> <span class="devsite-syntax-n">keeping</span> <span class="devsite-syntax-n">the</span> <span class="devsite-syntax-n">constructor</span> <span class="devsite-syntax-n">private</span> <span class="devsite-syntax-n">to</span> <span class="devsite-syntax-n">enforce</span> <span class="devsite-syntax-n">the</span> <span class="devsite-syntax-n">usage</span> <span class="devsite-syntax-n">of</span> <span class="devsite-syntax-n">getInstance</span> <span class="devsite-syntax-n">private</span> <span class="devsite-syntax-n">Repository</span><span class="devsite-syntax-p">()</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-n">User</span> <span class="devsite-syntax-n">user1</span> <span class="devsite-syntax-o">=</span> <span class="devsite-syntax-n">new</span> <span class="devsite-syntax-n">User</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-s2">"Jane"</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-s2">""</span><span class="devsite-syntax-p">);</span> <span class="devsite-syntax-n">User</span> <span class="devsite-syntax-n">user2</span> <span class="devsite-syntax-o">=</span> <span class="devsite-syntax-n">new</span> <span class="devsite-syntax-n">User</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-s2">"John"</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">null</span><span class="devsite-syntax-p">);</span> <span class="devsite-syntax-n">User</span> <span class="devsite-syntax-n">user3</span> <span class="devsite-syntax-o">=</span> <span class="devsite-syntax-n">new</span> <span class="devsite-syntax-n">User</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-s2">"Anne"</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-s2">"Doe"</span><span class="devsite-syntax-p">);</span> <span class="devsite-syntax-n">users</span> <span class="devsite-syntax-o">=</span> <span class="devsite-syntax-n">new</span> <span class="devsite-syntax-n">ArrayList</span><span class="devsite-syntax-p">();</span> <span class="devsite-syntax-n">users</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">add</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">user1</span><span class="devsite-syntax-p">);</span> <span class="devsite-syntax-n">users</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">add</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">user2</span><span class="devsite-syntax-p">);</span> <span class="devsite-syntax-n">users</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">add</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">user3</span><span class="devsite-syntax-p">);</span> <span class="devsite-syntax-p">}</span> <span class="devsite-syntax-n">public</span> <span class="devsite-syntax-n">List&lt;User&gt;</span> <span class="devsite-syntax-n">getUsers</span><span class="devsite-syntax-p">()</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">return</span> <span class="devsite-syntax-n">users</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-p">}</span> <span class="devsite-syntax-n">public</span> <span class="devsite-syntax-n">List&lt;String&gt;</span> <span class="devsite-syntax-n">getFormattedUserNames</span><span class="devsite-syntax-p">()</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-n">List&lt;String&gt;</span> <span class="devsite-syntax-n">userNames</span> <span class="devsite-syntax-o">=</span> <span class="devsite-syntax-n">new</span> <span class="devsite-syntax-n">ArrayList</span>&lt;&gt;<span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">users</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">size</span><span class="devsite-syntax-p">());</span> <span class="devsite-syntax-k">for</span> <span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">User</span> <span class="devsite-syntax-n">user</span> <span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">users</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-n">String</span> <span class="devsite-syntax-n">name</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-k">if</span> <span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">user</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">getLastName</span><span class="devsite-syntax-p">()</span> <span class="devsite-syntax-o">!=</span> <span class="devsite-syntax-n">null</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">if</span> <span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">user</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">getFirstName</span><span class="devsite-syntax-p">()</span> <span class="devsite-syntax-o">!=</span> <span class="devsite-syntax-n">null</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-n">name</span> <span class="devsite-syntax-o">=</span> <span class="devsite-syntax-n">user</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">getFirstName</span><span class="devsite-syntax-p">()</span> <span class="devsite-syntax-o">+</span> <span class="devsite-syntax-s2">" "</span> <span class="devsite-syntax-o">+</span> <span class="devsite-syntax-n">user</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">getLastName</span><span class="devsite-syntax-p">();</span> <span class="devsite-syntax-p">}</span> <span class="devsite-syntax-k">else</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-n">name</span> <span class="devsite-syntax-o">=</span> <span class="devsite-syntax-n">user</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">getLastName</span><span class="devsite-syntax-p">();</span> <span class="devsite-syntax-p">}</span> <span class="devsite-syntax-p">}</span> <span class="devsite-syntax-k">else</span> <span class="devsite-syntax-k">if</span> <span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">user</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">getFirstName</span><span class="devsite-syntax-p">()</span> <span class="devsite-syntax-o">!=</span> <span class="devsite-syntax-n">null</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-n">name</span> <span class="devsite-syntax-o">=</span> <span class="devsite-syntax-n">user</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">getFirstName</span><span class="devsite-syntax-p">();</span> <span class="devsite-syntax-p">}</span> <span class="devsite-syntax-k">else</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-n">name</span> <span class="devsite-syntax-o">=</span> <span class="devsite-syntax-s2">"Unknown"</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-p">}</span> <span class="devsite-syntax-n">userNames</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">add</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">name</span><span class="devsite-syntax-p">);</span> <span class="devsite-syntax-p">}</span> <span class="devsite-syntax-k">return</span> <span class="devsite-syntax-n">userNames</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-p">}</span> <span class="devsite-syntax-p">}</span> </code></pre></devsite-code> </google-codelab-step> <google-codelab-step label="Declaring nullability, val, var and data classes" duration="5" step="2"> <h2 class="step-title" id="2" data-text="Declaring nullability, val, var and data classes" tabindex="-1"> 3. Declaring nullability, val, var and data classes </h2> <p>Our IDE can do a pretty good job of automatically converting Java code into Kotlin code but sometimes it needs a little help. Let&#39;s let our IDE do an initial pass at the conversion. Then we&#39;ll go through the resulting code to understand how and why it has been converted this way.</p> <aside class="warning"><p>The auto-converter in future versions of Android Studio might create different results. The results shown below were done using Android Studio 4.0.</p> </aside> <p>Go to the <code translate="no" dir="ltr">User.java</code> file and convert it to Kotlin: <strong>Menu bar -&gt; Code -&gt; Convert Java File to Kotlin File</strong>.</p> <p>If your IDE prompts for correction after conversion, press <strong>Yes</strong>.</p> <p class="image-container"><img alt="e6f96eace5dabe5f.png" style="width: 390.00px" src="/static/codelabs/java-to-kotlin/img/e6f96eace5dabe5f.png" srcset="https://developer.android.com/static/codelabs/java-to-kotlin/img/e6f96eace5dabe5f_36.png 36w,https://developer.android.com/static/codelabs/java-to-kotlin/img/e6f96eace5dabe5f_48.png 48w,https://developer.android.com/static/codelabs/java-to-kotlin/img/e6f96eace5dabe5f_72.png 72w,https://developer.android.com/static/codelabs/java-to-kotlin/img/e6f96eace5dabe5f_96.png 96w,https://developer.android.com/static/codelabs/java-to-kotlin/img/e6f96eace5dabe5f_480.png 480w,https://developer.android.com/static/codelabs/java-to-kotlin/img/e6f96eace5dabe5f_720.png 720w,https://developer.android.com/static/codelabs/java-to-kotlin/img/e6f96eace5dabe5f_856.png 856w,https://developer.android.com/static/codelabs/java-to-kotlin/img/e6f96eace5dabe5f_960.png 960w,https://developer.android.com/static/codelabs/java-to-kotlin/img/e6f96eace5dabe5f_1440.png 1440w,https://developer.android.com/static/codelabs/java-to-kotlin/img/e6f96eace5dabe5f_1920.png 1920w,https://developer.android.com/static/codelabs/java-to-kotlin/img/e6f96eace5dabe5f_2880.png 2880w" sizes="(max-width: 840px) 100vw, 856px"></p> <p>You should see the following Kotlin code:</p> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="GDScript"><code translate="no" dir="ltr"><span class="devsite-syntax-k">class</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">User</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-k">var</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">firstName</span><span class="devsite-syntax-p">:</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nb devsite-syntax-nb-Type">String</span><span class="devsite-syntax-err">?</span><span class="devsite-syntax-p">,</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">var</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">lastName</span><span class="devsite-syntax-p">:</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nb devsite-syntax-nb-Type">String</span><span class="devsite-syntax-err">?</span><span class="devsite-syntax-p">)</span> </code></pre></devsite-code> <p>Note that <code translate="no" dir="ltr">User.java</code> was renamed to <code translate="no" dir="ltr">User.kt</code>. Kotlin files have the extension .kt.</p> <aside class="special"><p>Pro tip: If you paste Java code into a Kotlin file, the IDE will automatically convert the pasted code to Kotlin.</p> </aside> <p>In our Java <code translate="no" dir="ltr">User</code> class we had two properties: <code translate="no" dir="ltr">firstName</code> and <code translate="no" dir="ltr">lastName</code>. Each had a getter and setter method, making its value mutable. Kotlin&#39;s keyword for mutable variables is <code translate="no" dir="ltr">var</code>, so the converter uses <code translate="no" dir="ltr">var</code> for each of these properties. If our Java properties had only getters, they would be read-only and would have been declared as <code translate="no" dir="ltr">val</code> variables. <code translate="no" dir="ltr">val</code> is similar to the <code translate="no" dir="ltr">final</code> keyword in Java.</p> <p>One of the key differences between Kotlin and Java is that Kotlin explicitly specifies whether a variable can accept a null value. It does this by appending a <code translate="no" dir="ltr">?</code> to the type declaration.</p> <p>Because we marked <code translate="no" dir="ltr">firstName</code> and <code translate="no" dir="ltr">lastName</code> as nullable, the auto-converter automatically marked the properties as nullable with <code translate="no" dir="ltr">String?</code>. If you annotate your Java members as non-null (using <code translate="no" dir="ltr">org.jetbrains.annotations.NotNull</code> or <code translate="no" dir="ltr">androidx.annotation.NonNull</code>), the converter will recognize this and make the fields non-null in Kotlin as well.</p> <aside class="special"><p>Pro tip: In Kotlin, we recommend using read-only and immutable objects wherever possible (i.e. using <code translate="no" dir="ltr">val</code> instead of <code translate="no" dir="ltr">var</code>) and avoiding nullable types. You should strive to make nullability meaningful and something you want to handle specifically.</p> </aside> <p>The basic conversion is already done. But we can write this in a more idiomatic way. Let&#39;s see how.</p> <h3 is-upgraded id="data-class" data-text="Data class" tabindex="-1"><strong>Data class</strong></h3> <p>Our <code translate="no" dir="ltr">User</code> class only holds data. Kotlin has a keyword for classes with this role: <code translate="no" dir="ltr">data</code>. By marking this class as a <code translate="no" dir="ltr">data</code> class, the compiler will automatically create getters and setters for us. It will also derive the <code translate="no" dir="ltr">equals()</code>, <code translate="no" dir="ltr">hashCode()</code>, and <code translate="no" dir="ltr">toString()</code> functions.</p> <p>Let&#39;s add the <code translate="no" dir="ltr">data</code> keyword to our <code translate="no" dir="ltr">User</code> class:</p> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="GDScript"><code translate="no" dir="ltr"><span class="devsite-syntax-n">data</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">class</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">User</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-k">var</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">firstName</span><span class="devsite-syntax-p">:</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nb devsite-syntax-nb-Type">String</span><span class="devsite-syntax-err">?</span><span class="devsite-syntax-p">,</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">var</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">lastName</span><span class="devsite-syntax-p">:</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nb devsite-syntax-nb-Type">String</span><span class="devsite-syntax-err">?</span><span class="devsite-syntax-p">)</span> </code></pre></devsite-code> <p>Kotlin, like Java, can have a primary constructor and one or more secondary constructors. The one in the example above is the primary constructor of the <code translate="no" dir="ltr">User</code> class. If you&#39;re converting a Java class that has multiple constructors, the converter will automatically create multiple constructors in Kotlin as well. They are defined using the <code translate="no" dir="ltr">constructor</code> keyword.</p> <aside class="special"><p>Read more about constructors in the <a href="https://kotlinlang.org/docs/reference/classes.html#constructors" target="_blank">official documentation</a>.</p> </aside> <p>If we want to create an instance of this class, we can do it like this:</p> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="Text only"><code translate="no" dir="ltr">val user1 = User("Jane", "Doe") </code></pre></devsite-code> <h3 is-upgraded id="equality" data-text="Equality" tabindex="-1"><strong>Equality</strong></h3> <p>Kotlin has two types of equality:</p> <ul> <li>Structural equality uses the <code translate="no" dir="ltr">==</code> operator and calls <code translate="no" dir="ltr">equals()</code> to determine if two instances are equal.</li> <li>Referential equality uses the <code translate="no" dir="ltr">===</code> operator and checks if two references point to the same object.</li> </ul> <p>The properties defined in the primary constructor of the data class will be used for structural equality checks.</p> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="Text only"><code translate="no" dir="ltr">val user1 = User("Jane", "Doe") val user2 = User("Jane", "Doe") val structurallyEqual = user1 == user2 // true val referentiallyEqual = user1 === user2 // false </code></pre></devsite-code> <aside class="special"><p>Read more about data classes in the <a href="https://kotlinlang.org/docs/reference/data-classes.html#data-classes" target="_blank">official documentation</a>.</p> </aside> </google-codelab-step> <google-codelab-step label="Default arguments, named arguments" duration="5" step="3"> <h2 class="step-title" id="3" data-text="Default arguments, named arguments" tabindex="-1"> 4. Default arguments, named arguments </h2> <p>In Kotlin, we can assign default values to arguments in function calls. The default value is used when the argument is omitted. In Kotlin, constructors are also functions, so we can use default arguments to specify that the default value of <code translate="no" dir="ltr">lastName</code> is <code translate="no" dir="ltr">null</code>. To do this, we just assign <code translate="no" dir="ltr">null</code> to <code translate="no" dir="ltr">lastName</code>.</p> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="GDScript"><code translate="no" dir="ltr"><span class="devsite-syntax-n">data</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">class</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">User</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-k">var</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">firstName</span><span class="devsite-syntax-p">:</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nb devsite-syntax-nb-Type">String</span><span class="devsite-syntax-err">?</span><span class="devsite-syntax-p">,</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">var</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">lastName</span><span class="devsite-syntax-p">:</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nb devsite-syntax-nb-Type">String</span><span class="devsite-syntax-err">?</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">=</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nb devsite-syntax-nb-Type">null</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-o">//</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">usage</span> <span class="devsite-syntax-n">val</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">jane</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">=</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">User</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-s2">"Jane"</span><span class="devsite-syntax-p">)</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">//</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">same</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">as</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">User</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-s2">"Jane"</span><span class="devsite-syntax-p">,</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nb devsite-syntax-nb-Type">null</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-n">val</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">joe</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">=</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">User</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-s2">"Joe"</span><span class="devsite-syntax-p">,</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-s2">"Doe"</span><span class="devsite-syntax-p">)</span> </code></pre></devsite-code> <p>Kotlin allows you to label your arguments when your functions are called:</p> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="Text only"><code translate="no" dir="ltr">val john = User(firstName = "John", lastName = "Doe") </code></pre></devsite-code> <p>As a different use case, let&#39;s say that the <code translate="no" dir="ltr">firstName</code> has <code translate="no" dir="ltr">null</code> as its default value and <code translate="no" dir="ltr">lastName</code> does not. In this case, because the default parameter would precede a parameter with no default value, you must call the function with named arguments:</p> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="GDScript"><code translate="no" dir="ltr"><span class="devsite-syntax-n">data</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">class</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">User</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-k">var</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">firstName</span><span class="devsite-syntax-p">:</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nb devsite-syntax-nb-Type">String</span><span class="devsite-syntax-err">?</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">=</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nb devsite-syntax-nb-Type">null</span><span class="devsite-syntax-p">,</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">var</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">lastName</span><span class="devsite-syntax-p">:</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nb devsite-syntax-nb-Type">String</span><span class="devsite-syntax-err">?</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-o">//</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">usage</span> <span class="devsite-syntax-n">val</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">jane</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">=</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">User</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">lastName</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">=</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-s2">"Doe"</span><span class="devsite-syntax-p">)</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">//</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">same</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">as</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">User</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-nb devsite-syntax-nb-Type">null</span><span class="devsite-syntax-p">,</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-s2">"Doe"</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-n">val</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">john</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">=</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">User</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-s2">"John"</span><span class="devsite-syntax-p">,</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-s2">"Doe"</span><span class="devsite-syntax-p">)</span> </code></pre></devsite-code> <p>Default values are an important and often used concept in Kotlin code. In our codelab we want to always specify the first and last name in a <code translate="no" dir="ltr">User</code> object declaration, so we don&#39;t need default values.</p> <aside class="special"><p>If your function has multiple parameters, consider using <a href="https://kotlinlang.org/docs/reference/functions.html?_ga=2.40893098.969837971.1560273584-565456768.1516189658#named-arguments" target="_blank">named arguments</a> as they make the code more readable.</p> </aside> </google-codelab-step> <google-codelab-step label="Object initialization, companion object and singletons" duration="5" step="4"> <h2 class="step-title" id="4" data-text="Object initialization, companion object and singletons" tabindex="-1"> 5. Object initialization, companion object and singletons </h2> <p>Before continuing the codelab, make sure that your <code translate="no" dir="ltr">User</code> class is a <strong><code translate="no" dir="ltr">data</code></strong> class. Now, let&#39;s convert the <code translate="no" dir="ltr">Repository</code> class to Kotlin. The automatic conversion result should look like this:</p> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="Python"><code translate="no" dir="ltr"><span class="devsite-syntax-kn">import</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nn">java.util.</span><span class="devsite-syntax-o">*</span> <span class="devsite-syntax-k">class</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nc">Repository</span> <span class="devsite-syntax-n">private</span> <span class="devsite-syntax-n">constructor</span><span class="devsite-syntax-p">()</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-n">private</span> <span class="devsite-syntax-n">var</span> <span class="devsite-syntax-n">users</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">MutableList&lt;User</span><span class="devsite-syntax-err">?&gt;?</span> <span class="devsite-syntax-o">=</span> <span class="devsite-syntax-n">null</span> <span class="devsite-syntax-n">fun</span> <span class="devsite-syntax-n">getUsers</span><span class="devsite-syntax-p">():</span> <span class="devsite-syntax-n">List&lt;User</span><span class="devsite-syntax-err">?&gt;?</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">return</span> <span class="devsite-syntax-n">users</span> <span class="devsite-syntax-p">}</span> <span class="devsite-syntax-n">val</span> <span class="devsite-syntax-n">formattedUserNames</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">List&lt;String</span><span class="devsite-syntax-err">?</span>&gt; <span class="devsite-syntax-n">get</span><span class="devsite-syntax-p">()</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-n">val</span> <span class="devsite-syntax-n">userNames</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">MutableList&lt;String</span><span class="devsite-syntax-err">?</span>&gt; <span class="devsite-syntax-o">=</span> <span class="devsite-syntax-n">ArrayList</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">users</span><span class="devsite-syntax-err">!!</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">size</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-k">for</span> <span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">user</span> <span class="devsite-syntax-ow">in</span> <span class="devsite-syntax-n">users</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-n">var</span> <span class="devsite-syntax-n">name</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">String</span> <span class="devsite-syntax-n">name</span> <span class="devsite-syntax-o">=</span> <span class="devsite-syntax-k">if</span> <span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">user</span><span class="devsite-syntax-err">!!</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">lastName</span> <span class="devsite-syntax-o">!=</span> <span class="devsite-syntax-n">null</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">if</span> <span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">user</span><span class="devsite-syntax-err">!!</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">firstName</span> <span class="devsite-syntax-o">!=</span> <span class="devsite-syntax-n">null</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-n">user</span><span class="devsite-syntax-err">!!</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">firstName</span> <span class="devsite-syntax-o">+</span> <span class="devsite-syntax-s2">" "</span> <span class="devsite-syntax-o">+</span> <span class="devsite-syntax-n">user</span><span class="devsite-syntax-err">!!</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">lastName</span> <span class="devsite-syntax-p">}</span> <span class="devsite-syntax-k">else</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-n">user</span><span class="devsite-syntax-err">!!</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">lastName</span> <span class="devsite-syntax-p">}</span> <span class="devsite-syntax-p">}</span> <span class="devsite-syntax-k">else</span> <span class="devsite-syntax-k">if</span> <span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">user</span><span class="devsite-syntax-err">!!</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">firstName</span> <span class="devsite-syntax-o">!=</span> <span class="devsite-syntax-n">null</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-n">user</span><span class="devsite-syntax-err">!!</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">firstName</span> <span class="devsite-syntax-p">}</span> <span class="devsite-syntax-k">else</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-s2">"Unknown"</span> <span class="devsite-syntax-p">}</span> <span class="devsite-syntax-n">userNames</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">add</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">name</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">}</span> <span class="devsite-syntax-k">return</span> <span class="devsite-syntax-n">userNames</span> <span class="devsite-syntax-p">}</span> <span class="devsite-syntax-n">companion</span> <span class="devsite-syntax-nb">object</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-n">private</span> <span class="devsite-syntax-n">var</span> <span class="devsite-syntax-n">INSTANCE</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">Repository</span><span class="devsite-syntax-err">?</span> <span class="devsite-syntax-o">=</span> <span class="devsite-syntax-n">null</span> <span class="devsite-syntax-n">val</span> <span class="devsite-syntax-n">instance</span><span class="devsite-syntax-p">:</span> <span class="devsite-syntax-n">Repository</span><span class="devsite-syntax-err">?</span> <span class="devsite-syntax-n">get</span><span class="devsite-syntax-p">()</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">if</span> <span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">INSTANCE</span> <span class="devsite-syntax-o">==</span> <span class="devsite-syntax-n">null</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-n">synchronized</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">Repository</span><span class="devsite-syntax-p">::</span><span class="devsite-syntax-n">class</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">java</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-k">if</span> <span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">INSTANCE</span> <span class="devsite-syntax-o">==</span> <span class="devsite-syntax-n">null</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-n">INSTANCE</span> <span class="devsite-syntax-o">=</span> <span class="devsite-syntax-n">Repository</span><span class="devsite-syntax-p">()</span> <span class="devsite-syntax-p">}</span> <span class="devsite-syntax-p">}</span> <span class="devsite-syntax-p">}</span> <span class="devsite-syntax-k">return</span> <span class="devsite-syntax-n">INSTANCE</span> <span class="devsite-syntax-p">}</span> <span class="devsite-syntax-p">}</span> <span class="devsite-syntax-o">//</span> <span class="devsite-syntax-n">keeping</span> <span class="devsite-syntax-n">the</span> <span class="devsite-syntax-n">constructor</span> <span class="devsite-syntax-n">private</span> <span class="devsite-syntax-n">to</span> <span class="devsite-syntax-n">enforce</span> <span class="devsite-syntax-n">the</span> <span class="devsite-syntax-n">usage</span> <span class="devsite-syntax-n">of</span> <span class="devsite-syntax-n">getInstance</span> <span class="devsite-syntax-n">init</span> <span class="devsite-syntax-p">{</span> <span class="devsite-syntax-n">val</span> <span class="devsite-syntax-n">user1</span> <span class="devsite-syntax-o">=</span> <span class="devsite-syntax-n">User</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-s2">"Jane"</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-s2">""</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-n">val</span> <span class="devsite-syntax-n">user2</span> <span class="devsite-syntax-o">=</span> <span class="devsite-syntax-n">User</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-s2">"John"</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-n">null</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-n">val</span> <span class="devsite-syntax-n">user3</span> <span class="devsite-syntax-o">=</span> <span class="devsite-syntax-n">User</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-s2">"Anne"</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-s2">"Doe"</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-n">users</span> <span class="devsite-syntax-o">=</span> <span class="devsite-syntax-n">ArrayList&lt;Any</span><span class="devsite-syntax-err">?</span>&gt;<span class="devsite-syntax-p">()</span> <span class="devsite-syntax-n">users</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">add</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">user1</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-n">users</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">add</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">user2</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-n">users</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">add</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">user3</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">}</span> <span class="devsite-syntax-p">}</span> </code></pre></devsite-code> <p>Let&#39;s see what the automatic converter did:</p> <ul> <li>The list of <code translate="no" dir="ltr">users</code> is nullable since the object wasn&#39;t instantiated at declaration time</li> <li>Functions in Kotlin like <code translate="no" dir="ltr">getUsers()</code> are declared with the <code translate="no" dir="ltr">fun</code> modifier</li> <li>The <code translate="no" dir="ltr">getFormattedUserNames()</code> method is now a property called <code translate="no" dir="ltr">formattedUserNames</code></li> <li>The iteration over the list of users (that was initially part of <code translate="no" dir="ltr">getFormattedUserNames(</code>) ) has a different syntax than the Java one</li> <li>The <code translate="no" dir="ltr">static</code> field is now part of a <code translate="no" dir="ltr">companion object</code> block</li> <li>An <code translate="no" dir="ltr">init</code> block was added</li> </ul> <aside class="warning"><p><strong>Note</strong>: The generated code doesn&#39;t compile. Don&#39;t worry about it, we&#39;ll change it in the next steps.</p> </aside> <p>Before we go further, let&#39;s clean up the code a bit. If we look in the constructor, we notice the converter made our <code translate="no" dir="ltr">users</code> list a mutable list that holds nullable objects. While the list can indeed be null, let&#39;s assume it can&#39;t hold null users. So let&#39;s do the following:</p> <ul> <li>Remove the <code translate="no" dir="ltr">?</code> in <code translate="no" dir="ltr">User?</code> within the <code translate="no" dir="ltr">users</code> type declaration</li> <li>Remove the <code translate="no" dir="ltr">?</code> in <code translate="no" dir="ltr">User?</code> for the return type of <code translate="no" dir="ltr">getUsers()</code> so it returns <code translate="no" dir="ltr">List&lt;User&gt;?</code></li> </ul> <h3 is-upgraded id="init-block" data-text="Init block" tabindex="-1"><strong>Init block</strong></h3> <p>In Kotlin, the primary constructor cannot contain any code, so initialization code is placed in <code translate="no" dir="ltr">init</code> blocks. The functionality is the same.</p> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="GDScript"><code translate="no" dir="ltr"><span class="devsite-syntax-k">class</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">Repository</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">private</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">constructor</span><span class="devsite-syntax-p">()</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">{</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">...</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">init</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">{</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">val</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">user1</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">=</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">User</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-s2">"Jane"</span><span class="devsite-syntax-p">,</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-s2">""</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">val</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">user2</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">=</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">User</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-s2">"John"</span><span class="devsite-syntax-p">,</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nb devsite-syntax-nb-Type">null</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">val</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">user3</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">=</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">User</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-s2">"Anne"</span><span class="devsite-syntax-p">,</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-s2">"Doe"</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">users</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">=</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">ArrayList&lt;Any</span><span class="devsite-syntax-err">?</span>&gt;<span class="devsite-syntax-p">()</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">users</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">add</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">user1</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">users</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">add</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">user2</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">users</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">add</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">user3</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">}</span> <span class="devsite-syntax-p">}</span> </code></pre></devsite-code> <p>Much of the <code translate="no" dir="ltr">init</code> code handles initializing properties. This can also be done in the declaration of the property. For example, in the Kotlin version of our <code translate="no" dir="ltr">Repository</code> class, we see that the users property was initialized in the declaration.</p> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="GDScript"><code translate="no" dir="ltr"><span class="devsite-syntax-n">private</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">var</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">users</span><span class="devsite-syntax-p">:</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">MutableList&lt;User&gt;</span><span class="devsite-syntax-err">?</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">=</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nb devsite-syntax-nb-Type">null</span> </code></pre></devsite-code> <aside class="special"><p>Find out more about initializer blocks from the <a href="https://kotlinlang.org/docs/reference/classes.html#constructors" target="_blank">official documentation</a>.</p> </aside> <h3 is-upgraded id="kotlins-static-properties-and-methods" data-text="Kotlin's static properties and methods" tabindex="-1">Kotlin's <code translate="no" dir="ltr">static</code> <strong>properties and methods</strong></h3> <p>In Java, we use the <code translate="no" dir="ltr">static</code> keyword for fields or functions to say that they belong to a class but not to an instance of the class. This is why we created the <code translate="no" dir="ltr">INSTANCE</code> static field in our <code translate="no" dir="ltr">Repository</code> class. The Kotlin equivalent for this is the <code translate="no" dir="ltr">companion object</code> block. Here you would also declare the static fields and static functions. The converter created the companion object block and moved the <code translate="no" dir="ltr">INSTANCE</code> field here.</p> <h3 is-upgraded id="handling-singletons" data-text="Handling singletons" tabindex="-1"><strong>Handling singletons</strong></h3> <p>Because we need only one instance of the <code translate="no" dir="ltr">Repository</code> class, we used the <a href="https://en.wikipedia.org/wiki/Singleton_pattern" target="_blank">singleton pattern</a> in Java. With Kotlin, you can enforce this pattern at the compiler level by replacing the <code translate="no" dir="ltr">class</code> keyword with <code translate="no" dir="ltr">object</code>.</p> <p>Remove the private constructor and replace the class definition with <code translate="no" dir="ltr">object Repository</code>. Remove the companion object as well.</p> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="Scalate Server Page"><code translate="no" dir="ltr">object<span class="devsite-syntax-w"> </span>Repository<span class="devsite-syntax-w"> </span>{ <span class="devsite-syntax-w"> </span>private<span class="devsite-syntax-w"> </span>var<span class="devsite-syntax-w"> </span>users:<span class="devsite-syntax-w"> </span>MutableList&lt;User&gt;?<span class="devsite-syntax-w"> </span>=<span class="devsite-syntax-w"> </span>null <span class="devsite-syntax-w"> </span>fun<span class="devsite-syntax-w"> </span>getUsers():<span class="devsite-syntax-w"> </span>List&lt;User&gt;?<span class="devsite-syntax-w"> </span>{ <span class="devsite-syntax-w"> </span>return<span class="devsite-syntax-w"> </span>users <span class="devsite-syntax-w"> </span>} <span class="devsite-syntax-w"> </span>val<span class="devsite-syntax-w"> </span>formattedUserNames:<span class="devsite-syntax-w"> </span>List&lt;String&gt; <span class="devsite-syntax-w"> </span>get()<span class="devsite-syntax-w"> </span>{ <span class="devsite-syntax-w"> </span>val<span class="devsite-syntax-w"> </span>userNames:<span class="devsite-syntax-w"> </span>MutableList&lt;String&gt;<span class="devsite-syntax-w"> </span>= <span class="devsite-syntax-w"> </span>ArrayList(users!!.size) <span class="devsite-syntax-w"> </span>for<span class="devsite-syntax-w"> </span>(user<span class="devsite-syntax-w"> </span>in<span class="devsite-syntax-w"> </span>users)<span class="devsite-syntax-w"> </span>{ <span class="devsite-syntax-w"> </span>var<span class="devsite-syntax-w"> </span>name:<span class="devsite-syntax-w"> </span>String <span class="devsite-syntax-w"> </span>name<span class="devsite-syntax-w"> </span>=<span class="devsite-syntax-w"> </span>if<span class="devsite-syntax-w"> </span>(user!!.lastName<span class="devsite-syntax-w"> </span>!=<span class="devsite-syntax-w"> </span>null)<span class="devsite-syntax-w"> </span>{ <span class="devsite-syntax-w"> </span>if<span class="devsite-syntax-w"> </span>(user!!.firstName<span class="devsite-syntax-w"> </span>!=<span class="devsite-syntax-w"> </span>null)<span class="devsite-syntax-w"> </span>{ <span class="devsite-syntax-w"> </span>user!!.firstName<span class="devsite-syntax-w"> </span>+<span class="devsite-syntax-w"> </span>"<span class="devsite-syntax-w"> </span>"<span class="devsite-syntax-w"> </span>+<span class="devsite-syntax-w"> </span>user!!.lastName <span class="devsite-syntax-w"> </span>}<span class="devsite-syntax-w"> </span>else<span class="devsite-syntax-w"> </span>{ <span class="devsite-syntax-w"> </span>user!!.lastName <span class="devsite-syntax-w"> </span>} <span class="devsite-syntax-w"> </span>}<span class="devsite-syntax-w"> </span>else<span class="devsite-syntax-w"> </span>if<span class="devsite-syntax-w"> </span>(user!!.firstName<span class="devsite-syntax-w"> </span>!=<span class="devsite-syntax-w"> </span>null)<span class="devsite-syntax-w"> </span>{ <span class="devsite-syntax-w"> </span>user!!.firstName <span class="devsite-syntax-w"> </span>}<span class="devsite-syntax-w"> </span>else<span class="devsite-syntax-w"> </span>{ <span class="devsite-syntax-w"> </span>"Unknown" <span class="devsite-syntax-w"> </span>} <span class="devsite-syntax-w"> </span>userNames.add(name) <span class="devsite-syntax-w"> </span>} <span class="devsite-syntax-w"> </span>return<span class="devsite-syntax-w"> </span>userNames <span class="devsite-syntax-w"> </span>} <span class="devsite-syntax-w"> </span>//<span class="devsite-syntax-w"> </span>keeping<span class="devsite-syntax-w"> </span>the<span class="devsite-syntax-w"> </span>constructor<span class="devsite-syntax-w"> </span>private<span class="devsite-syntax-w"> </span>to<span class="devsite-syntax-w"> </span>enforce<span class="devsite-syntax-w"> </span>the<span class="devsite-syntax-w"> </span>usage<span class="devsite-syntax-w"> </span>of<span class="devsite-syntax-w"> </span>getInstance <span class="devsite-syntax-w"> </span>init<span class="devsite-syntax-w"> </span>{ <span class="devsite-syntax-w"> </span>val<span class="devsite-syntax-w"> </span>user1<span class="devsite-syntax-w"> </span>=<span class="devsite-syntax-w"> </span>User("Jane",<span class="devsite-syntax-w"> </span>"") <span class="devsite-syntax-w"> </span>val<span class="devsite-syntax-w"> </span>user2<span class="devsite-syntax-w"> </span>=<span class="devsite-syntax-w"> </span>User("John",<span class="devsite-syntax-w"> </span>null) <span class="devsite-syntax-w"> </span>val<span class="devsite-syntax-w"> </span>user3<span class="devsite-syntax-w"> </span>=<span class="devsite-syntax-w"> </span>User("Anne",<span class="devsite-syntax-w"> </span>"Doe") <span class="devsite-syntax-w"> </span>users<span class="devsite-syntax-w"> </span>=<span class="devsite-syntax-w"> </span>ArrayList&lt;Any?&gt;() <span class="devsite-syntax-w"> </span>users.add(user1) <span class="devsite-syntax-w"> </span>users.add(user2) <span class="devsite-syntax-w"> </span>users.add(user3) <span class="devsite-syntax-w"> </span>} } </code></pre></devsite-code> <p>When using the <code translate="no" dir="ltr">object</code> class, we just call functions and properties directly on the object, like this:</p> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="Text only"><code translate="no" dir="ltr">val formattedUserNames = Repository.formattedUserNames </code></pre></devsite-code> <p>Note that if a property does not have a visibility modifier on it, it is public by default, as in the case of <code translate="no" dir="ltr">formattedUserNames</code> property in the <code translate="no" dir="ltr">Repository</code> object.</p> <aside class="special"><p>Find out more about objects and companion objects from the <a href="https://kotlinlang.org/docs/tutorials/kotlin-for-py/objects-and-companion-objects.html" target="_blank">official documentation</a>.</p> </aside> </google-codelab-step> <google-codelab-step label="Handling nullability" duration="5" step="5"> <h2 class="step-title" id="5" data-text="Handling nullability" tabindex="-1"> 6. Handling nullability </h2> <p>When converting the <code translate="no" dir="ltr">Repository</code> class to Kotlin, the automatic converter made the list of users nullable, because it wasn&#39;t initialized to an object when it was declared. As a result, for all the usages of the <code translate="no" dir="ltr">users</code> object, the not-null assertion operator <code translate="no" dir="ltr">!!</code> needs to be used. (You&#39;ll see <code translate="no" dir="ltr">users!!</code> and <code translate="no" dir="ltr">user!!</code> throughout the converted code.) The <code translate="no" dir="ltr">!!</code> operator converts any variable to a non-null type, so you can access properties or call functions on it. However, an exception will be thrown if the variable value is indeed null. By using <code translate="no" dir="ltr">!!</code>, you&#39;re risking exceptions being thrown at runtime.</p> <p>Instead, prefer handling nullability by using one of these methods:</p> <ul> <li>Doing a null check ( <code translate="no" dir="ltr">if (users != null) {...}</code> )</li> <li>Using the <a href="https://kotlinlang.org/docs/reference/null-safety.html#elvis-operator" target="_blank">elvis operator</a> <code translate="no" dir="ltr">?:</code> (covered later in the codelab)</li> <li>Using some of the Kotlin standard functions (covered later in the codelab)</li> </ul> <aside class="special"><p>Find out more about null safety from the <a href="https://kotlinlang.org/docs/reference/null-safety.html#null-safety" target="_blank">official documentation</a>.</p> </aside> <p>In our case, we know that the list of users doesn&#39;t need to be nullable, since it&#39;s initialized right after the object is constructed (in the <code translate="no" dir="ltr">init</code> block). Thus we can directly instantiate the <code translate="no" dir="ltr">users</code> object when we declare it.</p> <p>When creating instances of collection types, Kotlin provides several helper functions to make your code more readable and flexible. Here we&#39;re using a <code translate="no" dir="ltr">MutableList</code> for <code translate="no" dir="ltr">users</code>:</p> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="GDScript"><code translate="no" dir="ltr"><span class="devsite-syntax-n">private</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">var</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">users</span><span class="devsite-syntax-p">:</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">MutableList&lt;User&gt;</span><span class="devsite-syntax-err">?</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">=</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nb devsite-syntax-nb-Type">null</span> </code></pre></devsite-code> <p>For simplicity, we can use the <a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/mutable-list-of.html" target="_blank"><code translate="no" dir="ltr">mutableListOf()</code></a> function and provide the list element type. <code translate="no" dir="ltr">mutableListOf&lt;User&gt;()</code> creates an empty list that can hold <code translate="no" dir="ltr">User</code> objects. Since the data type of the variable can now be inferred by the compiler, remove the explicit type declaration of the <code translate="no" dir="ltr">users</code> property.</p> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="Text only"><code translate="no" dir="ltr">private val users = mutableListOf&lt;User&gt;() </code></pre></devsite-code> <p>We also changed <code translate="no" dir="ltr">var</code> into <code translate="no" dir="ltr">val</code> because users will contain a read-only reference to the list of users. Note that the reference is read-only, so it can never point to a new list, but the list itself is still mutable (you can add or remove elements).</p> <p>Since the <code translate="no" dir="ltr">users</code> variable is already initialized, remove this initialization from the <code translate="no" dir="ltr">init</code> block:</p> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="Text only"><code translate="no" dir="ltr">users = ArrayList&lt;Any?&gt;() </code></pre></devsite-code> <p>Then the <code translate="no" dir="ltr">init</code> block should look like this:</p> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="Text only"><code translate="no" dir="ltr">init { val user1 = User("Jane", "") val user2 = User("John", null) val user3 = User("Anne", "Doe") users.add(user1) users.add(user2) users.add(user3) } </code></pre></devsite-code> <p>With these changes, our <code translate="no" dir="ltr">users</code> property is now non-null, and we can remove all the unnecessary <code translate="no" dir="ltr">!!</code> operator occurrences. Note that you will still see compile errors in Android Studio, but continue with the next few steps of the codelabs to resolve them.</p> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="Scalate Server Page"><code translate="no" dir="ltr">val<span class="devsite-syntax-w"> </span>userNames:<span class="devsite-syntax-w"> </span>MutableList&lt;String?&gt;<span class="devsite-syntax-w"> </span>=<span class="devsite-syntax-w"> </span>ArrayList(users.size) </code></pre></devsite-code> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="GDScript"><code translate="no" dir="ltr"><span class="devsite-syntax-k">for</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">user</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-ow">in</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">users</span><span class="devsite-syntax-p">)</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">{</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">var</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">name</span><span class="devsite-syntax-p">:</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nb devsite-syntax-nb-Type">String</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">name</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">=</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">if</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">user</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">lastName</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">!=</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nb devsite-syntax-nb-Type">null</span><span class="devsite-syntax-p">)</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">{</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">if</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">user</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">firstName</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">!=</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nb devsite-syntax-nb-Type">null</span><span class="devsite-syntax-p">)</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">{</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">user</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">firstName</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">+</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-s2">" "</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">+</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">user</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">lastName</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">}</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">else</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">{</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">user</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">lastName</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">}</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">}</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">else</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">if</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">user</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">firstName</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">!=</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nb devsite-syntax-nb-Type">null</span><span class="devsite-syntax-p">)</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">{</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">user</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">firstName</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">}</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">else</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">{</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-s2">"Unknown"</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">}</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">userNames</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">add</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">name</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">}</span> </code></pre></devsite-code> <p>Also, for the <code translate="no" dir="ltr">userNames</code> value, if you specify the type of <code translate="no" dir="ltr">ArrayList</code> as holding <code translate="no" dir="ltr">Strings</code>, then you can remove the explicit type in the declaration because it will be inferred.</p> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="Text only"><code translate="no" dir="ltr">val userNames = ArrayList&lt;String&gt;(users.size) </code></pre></devsite-code> <h3 is-upgraded id="destructuring" data-text="Destructuring" tabindex="-1"><strong>Destructuring</strong></h3> <p>Kotlin allows destructuring an object into a number of variables, using a syntax called <em>destructuring declaration</em>. We create multiple variables and can use them independently.</p> <p>For example, <code translate="no" dir="ltr">data</code> classes support destructuring so we can destructure the <code translate="no" dir="ltr">User</code> object in the <code translate="no" dir="ltr">for</code> loop into <code translate="no" dir="ltr">(firstName, lastName)</code>. This allows us to work directly with the <code translate="no" dir="ltr">firstName</code> and <code translate="no" dir="ltr">lastName</code> values. Update the <code translate="no" dir="ltr">for</code> loop as shown below. Replace all instances of <code translate="no" dir="ltr">user.firstName</code> with <code translate="no" dir="ltr">firstName</code> and replace <code translate="no" dir="ltr">user.lastName</code> with <code translate="no" dir="ltr">lastName</code>.</p> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="GDScript"><code translate="no" dir="ltr"><span class="devsite-syntax-k">for</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">((</span><span class="devsite-syntax-n">firstName</span><span class="devsite-syntax-p">,</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">lastName</span><span class="devsite-syntax-p">)</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-ow">in</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">users</span><span class="devsite-syntax-p">)</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">{</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">var</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">name</span><span class="devsite-syntax-p">:</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nb devsite-syntax-nb-Type">String</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">name</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">=</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">if</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">lastName</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">!=</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nb devsite-syntax-nb-Type">null</span><span class="devsite-syntax-p">)</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">{</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">if</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">firstName</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">!=</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nb devsite-syntax-nb-Type">null</span><span class="devsite-syntax-p">)</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">{</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">firstName</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">+</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-s2">" "</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">+</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">lastName</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">}</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">else</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">{</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">lastName</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">}</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">}</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">else</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">if</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">firstName</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">!=</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nb devsite-syntax-nb-Type">null</span><span class="devsite-syntax-p">)</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">{</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">firstName</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">}</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">else</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">{</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-s2">"Unknown"</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">}</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">userNames</span><span class="devsite-syntax-o">.</span><span class="devsite-syntax-n">add</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">name</span><span class="devsite-syntax-p">)</span> <span class="devsite-syntax-p">}</span> </code></pre></devsite-code> <aside class="special"><p>Read more about destructuring declarations in the <a href="https://kotlinlang.org/docs/reference/multi-declarations.html" target="_blank">official documentation</a>.</p> </aside> <h3 is-upgraded id="if-expression" data-text="if expression" tabindex="-1"><strong>if expression</strong></h3> <p>The names in the list of userNames are not quite in the format that we want yet. Since both <code translate="no" dir="ltr">lastName</code> and <code translate="no" dir="ltr">firstName</code> can be <code translate="no" dir="ltr">null</code>, we need to handle nullability when we build the list of formatted user names. We want to display <code translate="no" dir="ltr">"Unknown"</code> if either name is missing. Since the <code translate="no" dir="ltr">name</code> variable will not be changed after it&#39;s set once, we can use <code translate="no" dir="ltr">val</code> instead of <code translate="no" dir="ltr">var</code>. Make this change first.</p> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="Scalate Server Page"><code translate="no" dir="ltr">val<span class="devsite-syntax-w"> </span>name:<span class="devsite-syntax-w"> </span>String </code></pre></devsite-code> <p>Take a look at the code that sets the name variable. It may look new to you to see a variable being set to equal an <code translate="no" dir="ltr">if</code> / <code translate="no" dir="ltr">else</code> block of code. This is allowed because in Kotlin <code translate="no" dir="ltr">if</code> and <code translate="no" dir="ltr">when</code> are expressions—they return a value. The last line of the <code translate="no" dir="ltr">if</code> statement will be assigned to <code translate="no" dir="ltr">name</code>. This block&#39;s only purpose is to initialize the <code translate="no" dir="ltr">name</code> value.</p> <p>Essentially, this logic presented here is if the <code translate="no" dir="ltr">lastName</code> is null, <code translate="no" dir="ltr">name</code> is either set to the <code translate="no" dir="ltr">firstName</code> or <code translate="no" dir="ltr">"Unknown"</code>.</p> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="Text only"><code translate="no" dir="ltr">name = if (lastName != null) { if (firstName != null) { firstName + " " + lastName } else { lastName } } else if (firstName != null) { firstName } else { "Unknown" } </code></pre></devsite-code> <aside class="special"><p>Read more about <code translate="no" dir="ltr">if</code> and <code translate="no" dir="ltr">when</code> in the <a href="https://kotlinlang.org/docs/control-flow.html#if-expression" target="_blank">official documentation</a>.</p> </aside> <h3 is-upgraded id="elvis-operator" data-text="Elvis operator" tabindex="-1"><strong>Elvis operator</strong></h3> <p>This code can be written more idiomatically by using the <a href="https://en.wikipedia.org/wiki/Elvis_operator" target="_blank">elvis operator</a> <code translate="no" dir="ltr">?:</code>. The elvis operator will return the expression on its left hand side if it&#39;s not null, or the expression on its right hand side, if the left hand side is null.</p> <p>So in the following code, <code translate="no" dir="ltr">firstName</code> is returned if it is not null. If <code translate="no" dir="ltr">firstName</code> is null, the expression returns the value on the right hand , <code translate="no" dir="ltr">"Unknown"</code>:</p> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="Text only"><code translate="no" dir="ltr">name = if (lastName != null) { ... } else { firstName ?: "Unknown" } </code></pre></devsite-code> <aside class="special"><p>Read more about the elvis operator in the <a href="https://kotlinlang.org/docs/null-safety.html#elvis-operator" target="_blank">official documentation</a>.</p> </aside> </google-codelab-step> <google-codelab-step label="String templates" duration="5" step="6"> <h2 class="step-title" id="6" data-text="String templates" tabindex="-1"> 7. String templates </h2> <p>Kotlin makes working with <code translate="no" dir="ltr">String</code>s easy with <a href="https://kotlinlang.org/docs/reference/basic-syntax.html#using-string-templates" target="_blank"><em>String templates</em></a>. String templates allow you to reference variables inside string declarations by using the $ symbol before the variable. You could also put an expression within a string declaration, by placing the expression within { } and using the $ symbol before it. Example: <code translate="no" dir="ltr">${user.firstName}</code>.</p> <p>Your code currently uses string concatenation to combine the <code translate="no" dir="ltr">firstName</code> and <code translate="no" dir="ltr">lastName</code> into the user name.</p> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="Text only"><code translate="no" dir="ltr">if (firstName != null) { firstName + " " + lastName } </code></pre></devsite-code> <p>Instead, replace the String concatenation with:</p> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="Text only"><code translate="no" dir="ltr">if (firstName != null) { "$firstName $lastName" } </code></pre></devsite-code> <p>Using string templates can simplify your code.</p> <p>Your IDE will show you warnings if there is a more idiomatic way to write your code. You&#39;ll notice a squiggly underline in the code, and when you hover over it, you&#39;ll see a suggestion for how to refactor your code.</p> <p>Currently, you should see a warning that the <code translate="no" dir="ltr">name</code> declaration can be joined with the assignment. Let&#39;s apply this. Because the type of the <code translate="no" dir="ltr">name</code> variable can be deduced, we can remove the explicit <code translate="no" dir="ltr">String</code> type declaration. Now our <code translate="no" dir="ltr">formattedUserNames</code> looks like this:</p> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="Scalate Server Page"><code translate="no" dir="ltr">val<span class="devsite-syntax-w"> </span>formattedUserNames:<span class="devsite-syntax-w"> </span>List&lt;String?&gt; <span class="devsite-syntax-w"> </span>get()<span class="devsite-syntax-w"> </span>{ <span class="devsite-syntax-w"> </span>val<span class="devsite-syntax-w"> </span>userNames<span class="devsite-syntax-w"> </span>=<span class="devsite-syntax-w"> </span>ArrayList&lt;String&gt;(users.size) <span class="devsite-syntax-w"> </span>for<span class="devsite-syntax-w"> </span>((firstName,<span class="devsite-syntax-w"> </span>lastName)<span class="devsite-syntax-w"> </span>in<span class="devsite-syntax-w"> </span>users)<span class="devsite-syntax-w"> </span>{ <span class="devsite-syntax-w"> </span>val<span class="devsite-syntax-w"> </span>name<span class="devsite-syntax-w"> </span>=<span class="devsite-syntax-w"> </span>if<span class="devsite-syntax-w"> </span>(lastName<span class="devsite-syntax-w"> </span>!=<span class="devsite-syntax-w"> </span>null)<span class="devsite-syntax-w"> </span>{ <span class="devsite-syntax-w"> </span>if<span class="devsite-syntax-w"> </span>(firstName<span class="devsite-syntax-w"> </span>!=<span class="devsite-syntax-w"> </span>null)<span class="devsite-syntax-w"> </span>{ <span class="devsite-syntax-w"> </span>"$firstName<span class="devsite-syntax-w"> </span>$lastName" <span class="devsite-syntax-w"> </span>}<span class="devsite-syntax-w"> </span>else<span class="devsite-syntax-w"> </span>{ <span class="devsite-syntax-w"> </span>lastName <span class="devsite-syntax-w"> </span>} <span class="devsite-syntax-w"> </span>}<span class="devsite-syntax-w"> </span>else<span class="devsite-syntax-w"> </span>{ <span class="devsite-syntax-w"> </span>firstName<span class="devsite-syntax-w"> </span>?:<span class="devsite-syntax-w"> </span>"Unknown" <span class="devsite-syntax-w"> </span>} <span class="devsite-syntax-w"> </span>userNames.add(name) <span class="devsite-syntax-w"> </span>} <span class="devsite-syntax-w"> </span>return<span class="devsite-syntax-w"> </span>userNames <span class="devsite-syntax-w"> </span>} </code></pre></devsite-code> <p>We can make one additional tweak. Our UI logic displays <code translate="no" dir="ltr">"Unknown"</code> in case the first and last names are missing, so we&#39;re not supporting null objects. Thus, for the data type of <code translate="no" dir="ltr">formattedUserNames</code> replace <code translate="no" dir="ltr">List&lt;String?&gt;</code> with <code translate="no" dir="ltr">List&lt;String&gt;</code>.</p> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="Scalate Server Page"><code translate="no" dir="ltr">val<span class="devsite-syntax-w"> </span>formattedUserNames:<span class="devsite-syntax-w"> </span>List&lt;String&gt; </code></pre></devsite-code> </google-codelab-step> <google-codelab-step label="Operations on collections" duration="5" step="7"> <h2 class="step-title" id="7" data-text="Operations on collections" tabindex="-1"> 8. Operations on collections </h2> <p>Let&#39;s take a closer look at the <code translate="no" dir="ltr">formattedUserNames</code> getter and see how we can make it more idiomatic. Right now the code does the following:</p> <ul> <li>Creates a new list of strings</li> <li>Iterates through the list of users</li> <li>Constructs the formatted name for each user, based on the user&#39;s first and last name</li> <li>Returns the newly created list</li> </ul> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="Scalate Server Page"><code translate="no" dir="ltr"><span class="devsite-syntax-w"> </span>val<span class="devsite-syntax-w"> </span>formattedUserNames:<span class="devsite-syntax-w"> </span>List&lt;String&gt; <span class="devsite-syntax-w"> </span>get()<span class="devsite-syntax-w"> </span>{ <span class="devsite-syntax-w"> </span>val<span class="devsite-syntax-w"> </span>userNames<span class="devsite-syntax-w"> </span>=<span class="devsite-syntax-w"> </span>ArrayList&lt;String&gt;(users.size) <span class="devsite-syntax-w"> </span>for<span class="devsite-syntax-w"> </span>((firstName,<span class="devsite-syntax-w"> </span>lastName)<span class="devsite-syntax-w"> </span>in<span class="devsite-syntax-w"> </span>users)<span class="devsite-syntax-w"> </span>{ <span class="devsite-syntax-w"> </span>val<span class="devsite-syntax-w"> </span>name<span class="devsite-syntax-w"> </span>=<span class="devsite-syntax-w"> </span>if<span class="devsite-syntax-w"> </span>(lastName<span class="devsite-syntax-w"> </span>!=<span class="devsite-syntax-w"> </span>null)<span class="devsite-syntax-w"> </span>{ <span class="devsite-syntax-w"> </span>if<span class="devsite-syntax-w"> </span>(firstName<span class="devsite-syntax-w"> </span>!=<span class="devsite-syntax-w"> </span>null)<span class="devsite-syntax-w"> </span>{ <span class="devsite-syntax-w"> </span>"$firstName<span class="devsite-syntax-w"> </span>$lastName" <span class="devsite-syntax-w"> </span>}<span class="devsite-syntax-w"> </span>else<span class="devsite-syntax-w"> </span>{ <span class="devsite-syntax-w"> </span>lastName <span class="devsite-syntax-w"> </span>} <span class="devsite-syntax-w"> </span>}<span class="devsite-syntax-w"> </span>else<span class="devsite-syntax-w"> </span>{ <span class="devsite-syntax-w"> </span>firstName<span class="devsite-syntax-w"> </span>?:<span class="devsite-syntax-w"> </span>"Unknown" <span class="devsite-syntax-w"> </span>} <span class="devsite-syntax-w"> </span>userNames.add(name) <span class="devsite-syntax-w"> </span>} <span class="devsite-syntax-w"> </span>return<span class="devsite-syntax-w"> </span>userNames <span class="devsite-syntax-w"> </span>} </code></pre></devsite-code> <p>Kotlin provides an extensive list of <a href="https://kotlinlang.org/docs/reference/collection-transformations.html" target="_blank">collection transformations</a> that make development faster and safer by expanding the capabilities of the Java Collections API. One of them is the <a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/map.html" target="_blank"><code translate="no" dir="ltr">map</code></a> function. This function returns a new list containing the results of applying the given transform function to each element in the original list. So, instead of creating a new list and iterating through the list of users manually, we can use the <code translate="no" dir="ltr">map</code> function and move the logic we had in the <code translate="no" dir="ltr">for</code> loop inside the <code translate="no" dir="ltr">map</code> body. By default, the name of the current list item used in <code translate="no" dir="ltr">map</code> is <a href="https://kotlinlang.org/docs/reference/lambdas.html?_ga=2.51454505.1883141324.1588651372-527214030.1582762539#it-implicit-name-of-a-single-parameter" target="_blank"><code translate="no" dir="ltr">it</code></a>, but for readability you can replace <code translate="no" dir="ltr">it</code> with your own variable name. In our case, let&#39;s name it <code translate="no" dir="ltr">user</code>:</p> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="Scalate Server Page"><code translate="no" dir="ltr">val<span class="devsite-syntax-w"> </span>formattedUserNames:<span class="devsite-syntax-w"> </span>List&lt;String&gt; <span class="devsite-syntax-w"> </span>get()<span class="devsite-syntax-w"> </span>{ <span class="devsite-syntax-w"> </span>return<span class="devsite-syntax-w"> </span>users.map<span class="devsite-syntax-w"> </span>{<span class="devsite-syntax-w"> </span>user<span class="devsite-syntax-w"> </span>-&gt; <span class="devsite-syntax-w"> </span>val<span class="devsite-syntax-w"> </span>name<span class="devsite-syntax-w"> </span>=<span class="devsite-syntax-w"> </span>if<span class="devsite-syntax-w"> </span>(user.lastName<span class="devsite-syntax-w"> </span>!=<span class="devsite-syntax-w"> </span>null)<span class="devsite-syntax-w"> </span>{ <span class="devsite-syntax-w"> </span>if<span class="devsite-syntax-w"> </span>(user.firstName<span class="devsite-syntax-w"> </span>!=<span class="devsite-syntax-w"> </span>null)<span class="devsite-syntax-w"> </span>{ <span class="devsite-syntax-w"> </span>"${user.firstName}<span class="devsite-syntax-w"> </span>${user.lastName}" <span class="devsite-syntax-w"> </span>}<span class="devsite-syntax-w"> </span>else<span class="devsite-syntax-w"> </span>{ <span class="devsite-syntax-w"> </span>user.lastName<span class="devsite-syntax-w"> </span>?:<span class="devsite-syntax-w"> </span>"Unknown" <span class="devsite-syntax-w"> </span>} <span class="devsite-syntax-w"> </span>}<span class="devsite-syntax-w"> </span>else<span class="devsite-syntax-w"> </span>{ <span class="devsite-syntax-w"> </span>user.firstName<span class="devsite-syntax-w"> </span>?:<span class="devsite-syntax-w"> </span>"Unknown" <span class="devsite-syntax-w"> </span>} <span class="devsite-syntax-w"> </span>name <span class="devsite-syntax-w"> </span>} <span class="devsite-syntax-w"> </span>} </code></pre></devsite-code> <p>Notice that we use the Elvis operator to return <code translate="no" dir="ltr">"Unknown"</code> if <code translate="no" dir="ltr">user.lastName</code> is null, since <code translate="no" dir="ltr">user.lastName</code> is of type <code translate="no" dir="ltr">String?</code> and a <code translate="no" dir="ltr">String</code> is required for the <code translate="no" dir="ltr">name</code>.</p> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="Text only"><code translate="no" dir="ltr">... else { user.lastName ?: "Unknown" } ... </code></pre></devsite-code> <p>To simplify this even more, we can remove the <code translate="no" dir="ltr">name</code> variable completely:</p> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="Scalate Server Page"><code translate="no" dir="ltr">val<span class="devsite-syntax-w"> </span>formattedUserNames:<span class="devsite-syntax-w"> </span>List&lt;String&gt; <span class="devsite-syntax-w"> </span>get()<span class="devsite-syntax-w"> </span>{ <span class="devsite-syntax-w"> </span>return<span class="devsite-syntax-w"> </span>users.map<span class="devsite-syntax-w"> </span>{<span class="devsite-syntax-w"> </span>user<span class="devsite-syntax-w"> </span>-&gt; <span class="devsite-syntax-w"> </span>if<span class="devsite-syntax-w"> </span>(user.lastName<span class="devsite-syntax-w"> </span>!=<span class="devsite-syntax-w"> </span>null)<span class="devsite-syntax-w"> </span>{ <span class="devsite-syntax-w"> </span>if<span class="devsite-syntax-w"> </span>(user.firstName<span class="devsite-syntax-w"> </span>!=<span class="devsite-syntax-w"> </span>null)<span class="devsite-syntax-w"> </span>{ <span class="devsite-syntax-w"> </span>"${user.firstName}<span class="devsite-syntax-w"> </span>${user.lastName}" <span class="devsite-syntax-w"> </span>}<span class="devsite-syntax-w"> </span>else<span class="devsite-syntax-w"> </span>{ <span class="devsite-syntax-w"> </span>user.lastName<span class="devsite-syntax-w"> </span>?:<span class="devsite-syntax-w"> </span>"Unknown" <span class="devsite-syntax-w"> </span>} <span class="devsite-syntax-w"> </span>}<span class="devsite-syntax-w"> </span>else<span class="devsite-syntax-w"> </span>{ <span class="devsite-syntax-w"> </span>user.firstName<span class="devsite-syntax-w"> </span>?:<span class="devsite-syntax-w"> </span>"Unknown" <span class="devsite-syntax-w"> </span>} <span class="devsite-syntax-w"> </span>} <span class="devsite-syntax-w"> </span>} </code></pre></devsite-code> <aside class="special"><p>As well as collection transformations, the Kotlin Standard Library provides a wide array of tools to manage your <a href="https://kotlinlang.org/docs/reference/collections-overview.html" target="_blank">collections</a>. From different collection types to a variety of <a href="https://kotlinlang.org/docs/reference/collection-operations.html" target="_blank">operations</a> specific to either the general <code translate="no" dir="ltr">Collection</code> type or to different subtypes like <a href="https://kotlinlang.org/docs/reference/list-operations.html" target="_blank"><code translate="no" dir="ltr">List</code></a> or <a href="https://kotlinlang.org/docs/reference/set-operations.html" target="_blank"><code translate="no" dir="ltr">Set</code></a>.</p> <p>In general, when working with collections, make sure you check whether the functionality you&#39;re planning on writing in Kotlin is already implemented by the Standard Library and prefer using that one to your own implementation.</p> </aside> </google-codelab-step> <google-codelab-step label="Properties and backing properties" duration="5" step="8"> <h2 class="step-title" id="8" data-text="Properties and backing properties" tabindex="-1"> 9. Properties and backing properties </h2> <p>We saw that the automatic converter replaced the <code translate="no" dir="ltr">getFormattedUserNames()</code> function with a property called <code translate="no" dir="ltr">formattedUserNames</code> that has a custom getter. Under the hood, Kotlin still generates a <code translate="no" dir="ltr">getFormattedUserNames()</code> method that returns a <code translate="no" dir="ltr">List</code>.</p> <p>In Java, we would expose our class properties via getter and setter functions. Kotlin allows us to have a better differentiation between properties of a class, expressed with fields, and functionalities, actions that a class can do, expressed with functions. In our case, the <code translate="no" dir="ltr">Repository</code> class is very simple and doesn&#39;t do any actions so it only has fields.</p> <p>The logic that was triggered in the Java <code translate="no" dir="ltr">getFormattedUserNames()</code> function is now triggered when calling the getter of the <code translate="no" dir="ltr">formattedUserNames</code> Kotlin property.</p> <p>While we don&#39;t explicitly have a field corresponding to the <code translate="no" dir="ltr">formattedUserNames</code> property, Kotlin does provide us an automatic backing field named <code translate="no" dir="ltr">field</code> which we can access if needed from custom getters and setters.</p> <p>Sometimes, however, we want some extra functionality that the automatic backing field doesn&#39;t provide.</p> <p>Let&#39;s go through an example.</p> <p>Inside our <code translate="no" dir="ltr">Repository</code> class, we have a mutable list of users which is being exposed in the function <code translate="no" dir="ltr">getUsers()</code> which was generated from our Java code:</p> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="Text only"><code translate="no" dir="ltr">fun getUsers(): List&lt;User&gt;? { return users } </code></pre></devsite-code> <p>Because we didn&#39;t want the callers of the <code translate="no" dir="ltr">Repository</code> class to modify the users list, we created the <code translate="no" dir="ltr">getUsers()</code> function that returns a read-only <code translate="no" dir="ltr">List&lt;User&gt;</code>. With Kotlin, we prefer using properties rather than functions for such cases. More precisely, we would expose a read-only <code translate="no" dir="ltr">List&lt;User&gt;</code> that is backed by a <code translate="no" dir="ltr">mutableListOf&lt;User&gt;</code>.</p> <p>First, let&#39;s rename <code translate="no" dir="ltr">users</code> to <code translate="no" dir="ltr">_users</code>. Highlight the variable name, right click to <strong>Refactor &gt; Rename</strong> the variable. Then add a public read-only property that returns a list of users. Let&#39;s call it <code translate="no" dir="ltr">users</code>:</p> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="Scalate Server Page"><code translate="no" dir="ltr">private<span class="devsite-syntax-w"> </span>val<span class="devsite-syntax-w"> </span>_users<span class="devsite-syntax-w"> </span>=<span class="devsite-syntax-w"> </span>mutableListOf&lt;User&gt;() val<span class="devsite-syntax-w"> </span>users:<span class="devsite-syntax-w"> </span>List&lt;User&gt; <span class="devsite-syntax-w"> </span>get()<span class="devsite-syntax-w"> </span>=<span class="devsite-syntax-w"> </span>_users </code></pre></devsite-code> <p>At this point, you can delete the <code translate="no" dir="ltr">getUsers()</code> method.</p> <p>With the above change, the private <code translate="no" dir="ltr">_users</code> property becomes the <em>backing property</em> for the public <code translate="no" dir="ltr">users</code> property. Outside of the <code translate="no" dir="ltr">Repository</code> class, the <code translate="no" dir="ltr">_users</code> list is not modifiable, as consumers of the class can access the list only through <code translate="no" dir="ltr">users</code>.</p> <p>When <code translate="no" dir="ltr">users</code> is called from Kotlin code, the <code translate="no" dir="ltr">List</code> implementation from the Kotlin Standard Library is used, where the list is not modifiable. If <code translate="no" dir="ltr">users</code> is called from Java, the <code translate="no" dir="ltr">java.util.List</code> implementation is used, where the list is modifiable and operations like add() and remove() are available.</p> <aside class="special"><p>The convention for backing properties is to use a leading underscore.</p> <p>Find out more about properties from the <a href="https://kotlinlang.org/docs/reference/properties.html#properties-and-fields" target="_blank">official documentation</a>.</p> </aside> <p>Full code:</p> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="Scalate Server Page"><code translate="no" dir="ltr">object<span class="devsite-syntax-w"> </span>Repository<span class="devsite-syntax-w"> </span>{ <span class="devsite-syntax-w"> </span>private<span class="devsite-syntax-w"> </span>val<span class="devsite-syntax-w"> </span>_users<span class="devsite-syntax-w"> </span>=<span class="devsite-syntax-w"> </span>mutableListOf&lt;User&gt;() <span class="devsite-syntax-w"> </span>val<span class="devsite-syntax-w"> </span>users:<span class="devsite-syntax-w"> </span>List&lt;User&gt; <span class="devsite-syntax-w"> </span>get()<span class="devsite-syntax-w"> </span>=<span class="devsite-syntax-w"> </span>_users <span class="devsite-syntax-w"> </span>val<span class="devsite-syntax-w"> </span>formattedUserNames:<span class="devsite-syntax-w"> </span>List&lt;String&gt; <span class="devsite-syntax-w"> </span>get()<span class="devsite-syntax-w"> </span>{ <span class="devsite-syntax-w"> </span>return<span class="devsite-syntax-w"> </span>_users.map<span class="devsite-syntax-w"> </span>{<span class="devsite-syntax-w"> </span>user<span class="devsite-syntax-w"> </span>-&gt; <span class="devsite-syntax-w"> </span>if<span class="devsite-syntax-w"> </span>(user.lastName<span class="devsite-syntax-w"> </span>!=<span class="devsite-syntax-w"> </span>null)<span class="devsite-syntax-w"> </span>{ <span class="devsite-syntax-w"> </span>if<span class="devsite-syntax-w"> </span>(user.firstName<span class="devsite-syntax-w"> </span>!=<span class="devsite-syntax-w"> </span>null)<span class="devsite-syntax-w"> </span>{ <span class="devsite-syntax-w"> </span>"${user.firstName}<span class="devsite-syntax-w"> </span>${user.lastName}" <span class="devsite-syntax-w"> </span>}<span class="devsite-syntax-w"> </span>else<span class="devsite-syntax-w"> </span>{ <span class="devsite-syntax-w"> </span>user.lastName<span class="devsite-syntax-w"> </span>?:<span class="devsite-syntax-w"> </span>"Unknown" <span class="devsite-syntax-w"> </span>} <span class="devsite-syntax-w"> </span>}<span class="devsite-syntax-w"> </span>else<span class="devsite-syntax-w"> </span>{ <span class="devsite-syntax-w"> </span>user.firstName<span class="devsite-syntax-w"> </span>?:<span class="devsite-syntax-w"> </span>"Unknown" <span class="devsite-syntax-w"> </span>} <span class="devsite-syntax-w"> </span>} <span class="devsite-syntax-w"> </span>} <span class="devsite-syntax-w"> </span>init<span class="devsite-syntax-w"> </span>{ <span class="devsite-syntax-w"> </span>val<span class="devsite-syntax-w"> </span>user1<span class="devsite-syntax-w"> </span>=<span class="devsite-syntax-w"> </span>User("Jane",<span class="devsite-syntax-w"> </span>"") <span class="devsite-syntax-w"> </span>val<span class="devsite-syntax-w"> </span>user2<span class="devsite-syntax-w"> </span>=<span class="devsite-syntax-w"> </span>User("John",<span class="devsite-syntax-w"> </span>null) <span class="devsite-syntax-w"> </span>val<span class="devsite-syntax-w"> </span>user3<span class="devsite-syntax-w"> </span>=<span class="devsite-syntax-w"> </span>User("Anne",<span class="devsite-syntax-w"> </span>"Doe") <span class="devsite-syntax-w"> </span>_users.add(user1) <span class="devsite-syntax-w"> </span>_users.add(user2) <span class="devsite-syntax-w"> </span>_users.add(user3) <span class="devsite-syntax-w"> </span>} } </code></pre></devsite-code> </google-codelab-step> <google-codelab-step label="Top-level and extension functions and properties" duration="5" step="9"> <h2 class="step-title" id="9" data-text="Top-level and extension functions and properties" tabindex="-1"> 10. Top-level and extension functions and properties </h2> <p>Right now the <code translate="no" dir="ltr">Repository</code> class knows how to compute the formatted user name for a <code translate="no" dir="ltr">User</code> object. But if we want to reuse the same formatting logic in other classes, we need to either copy and paste it or move it to the <code translate="no" dir="ltr">User</code> class.</p> <p>Kotlin provides the ability to declare functions and properties outside of any class, object, or interface. For example, the <code translate="no" dir="ltr">mutableListOf()</code> function we used to create a new instance of a <code translate="no" dir="ltr">List</code> is already defined in <a href="https://github.com/JetBrains/kotlin/blob/master/libraries/stdlib/src/kotlin/collections/Collections.kt#L90" target="_blank"><code translate="no" dir="ltr">Collections.kt</code></a> from the Kotlin Standard Library.</p> <p>In Java, whenever you need some utility functionality, you would most likely create a <code translate="no" dir="ltr">Util</code> class and declare that functionality as a static function. In Kotlin you can declare top-level functions, without having a class. However, Kotlin also provides the ability to create <strong>extension functions</strong>. These are functions that extend a certain type but are declared outside of the type.</p> <aside class="special"><p>To extend the functionality of a class, either because we don&#39;t own the class or because it&#39;s not open to inheritance, Kotlin created special declarations called <strong>extensions</strong>. Kotlin supports extension functions and extension properties.</p> </aside> <p>The visibility of extension functions and properties can be restricted by using visibility modifiers. These restrict the usage only to classes that need the extensions, and don&#39;t pollute the namespace.</p> <p>For the <code translate="no" dir="ltr">User</code> class, we can either add an extension function that computes the formatted name, or we can hold the formatted name in an extension property. It can be added outside the <code translate="no" dir="ltr">Repository</code> class, in the same file:</p> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="Scilab"><code translate="no" dir="ltr"><span class="devsite-syntax-c1">// extension function</span> <span class="devsite-syntax-n">fun</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">User</span><span class="devsite-syntax-p">.</span><span class="devsite-syntax-n">getFormattedName</span><span class="devsite-syntax-p">():</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">String</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">{</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">return</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">if</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">lastName</span><span class="devsite-syntax-w"> </span>!<span class="devsite-syntax-p">=</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nb">null</span><span class="devsite-syntax-p">)</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">{</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">if</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">firstName</span><span class="devsite-syntax-w"> </span>!<span class="devsite-syntax-p">=</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nb">null</span><span class="devsite-syntax-p">)</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">{</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-s">"$firstName $lastName"</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">}</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">else</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">{</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">lastName</span><span class="devsite-syntax-w"> </span>?<span class="devsite-syntax-p">:</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-s">"Unknown"</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">}</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">}</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">else</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">{</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">firstName</span><span class="devsite-syntax-w"> </span>?<span class="devsite-syntax-p">:</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-s">"Unknown"</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">}</span> <span class="devsite-syntax-p">}</span> <span class="devsite-syntax-c1">// extension property</span> <span class="devsite-syntax-n">val</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">User</span><span class="devsite-syntax-p">.</span><span class="devsite-syntax-n">userFormattedName</span><span class="devsite-syntax-p">:</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">String</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">get</span><span class="devsite-syntax-p">()</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">{</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">return</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">if</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">lastName</span><span class="devsite-syntax-w"> </span>!<span class="devsite-syntax-p">=</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nb">null</span><span class="devsite-syntax-p">)</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">{</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">if</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-n">firstName</span><span class="devsite-syntax-w"> </span>!<span class="devsite-syntax-p">=</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nb">null</span><span class="devsite-syntax-p">)</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">{</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-s">"$firstName $lastName"</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">}</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">else</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">{</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">lastName</span><span class="devsite-syntax-w"> </span>?<span class="devsite-syntax-p">:</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-s">"Unknown"</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">}</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">}</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">else</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">{</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">firstName</span><span class="devsite-syntax-w"> </span>?<span class="devsite-syntax-p">:</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-s">"Unknown"</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">}</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">}</span> <span class="devsite-syntax-c1">// usage:</span> <span class="devsite-syntax-n">val</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nb">user</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">=</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">User</span><span class="devsite-syntax-p">(...)</span> <span class="devsite-syntax-n">val</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">name</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">=</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nb">user</span><span class="devsite-syntax-p">.</span><span class="devsite-syntax-n">getFormattedName</span><span class="devsite-syntax-p">()</span> <span class="devsite-syntax-n">val</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">formattedName</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">=</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nb">user</span><span class="devsite-syntax-p">.</span><span class="devsite-syntax-n">userFormattedName</span> </code></pre></devsite-code> <p>We can then use the extension functions and properties as if they&#39;re part of the <code translate="no" dir="ltr">User</code> class.</p> <p>Because the formatted name is a property of the <code translate="no" dir="ltr">User</code> class and not a functionality of the <code translate="no" dir="ltr">Repository</code> class, let&#39;s use the extension property. Our <code translate="no" dir="ltr">Repository</code> file now looks like this:</p> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="Scalate Server Page"><code translate="no" dir="ltr">val<span class="devsite-syntax-w"> </span>User.formattedName:<span class="devsite-syntax-w"> </span>String <span class="devsite-syntax-w"> </span>get()<span class="devsite-syntax-w"> </span>{ <span class="devsite-syntax-w"> </span>return<span class="devsite-syntax-w"> </span>if<span class="devsite-syntax-w"> </span>(lastName<span class="devsite-syntax-w"> </span>!=<span class="devsite-syntax-w"> </span>null)<span class="devsite-syntax-w"> </span>{ <span class="devsite-syntax-w"> </span>if<span class="devsite-syntax-w"> </span>(firstName<span class="devsite-syntax-w"> </span>!=<span class="devsite-syntax-w"> </span>null)<span class="devsite-syntax-w"> </span>{ <span class="devsite-syntax-w"> </span>"$firstName<span class="devsite-syntax-w"> </span>$lastName" <span class="devsite-syntax-w"> </span>}<span class="devsite-syntax-w"> </span>else<span class="devsite-syntax-w"> </span>{ <span class="devsite-syntax-w"> </span>lastName<span class="devsite-syntax-w"> </span>?:<span class="devsite-syntax-w"> </span>"Unknown" <span class="devsite-syntax-w"> </span>} <span class="devsite-syntax-w"> </span>}<span class="devsite-syntax-w"> </span>else<span class="devsite-syntax-w"> </span>{ <span class="devsite-syntax-w"> </span>firstName<span class="devsite-syntax-w"> </span>?:<span class="devsite-syntax-w"> </span>"Unknown" <span class="devsite-syntax-w"> </span>} <span class="devsite-syntax-w"> </span>} object<span class="devsite-syntax-w"> </span>Repository<span class="devsite-syntax-w"> </span>{ <span class="devsite-syntax-w"> </span>private<span class="devsite-syntax-w"> </span>val<span class="devsite-syntax-w"> </span>_users<span class="devsite-syntax-w"> </span>=<span class="devsite-syntax-w"> </span>mutableListOf&lt;User&gt;() <span class="devsite-syntax-w"> </span>val<span class="devsite-syntax-w"> </span>users:<span class="devsite-syntax-w"> </span>List&lt;User&gt; <span class="devsite-syntax-w"> </span>get()<span class="devsite-syntax-w"> </span>=<span class="devsite-syntax-w"> </span>_users <span class="devsite-syntax-w"> </span>val<span class="devsite-syntax-w"> </span>formattedUserNames:<span class="devsite-syntax-w"> </span>List&lt;String&gt; <span class="devsite-syntax-w"> </span>get()<span class="devsite-syntax-w"> </span>{ <span class="devsite-syntax-w"> </span>return<span class="devsite-syntax-w"> </span>_users.map<span class="devsite-syntax-w"> </span>{<span class="devsite-syntax-w"> </span>user<span class="devsite-syntax-w"> </span>-&gt;<span class="devsite-syntax-w"> </span>user.formattedName<span class="devsite-syntax-w"> </span>} <span class="devsite-syntax-w"> </span>} <span class="devsite-syntax-w"> </span>init<span class="devsite-syntax-w"> </span>{ <span class="devsite-syntax-w"> </span>val<span class="devsite-syntax-w"> </span>user1<span class="devsite-syntax-w"> </span>=<span class="devsite-syntax-w"> </span>User("Jane",<span class="devsite-syntax-w"> </span>"") <span class="devsite-syntax-w"> </span>val<span class="devsite-syntax-w"> </span>user2<span class="devsite-syntax-w"> </span>=<span class="devsite-syntax-w"> </span>User("John",<span class="devsite-syntax-w"> </span>null) <span class="devsite-syntax-w"> </span>val<span class="devsite-syntax-w"> </span>user3<span class="devsite-syntax-w"> </span>=<span class="devsite-syntax-w"> </span>User("Anne",<span class="devsite-syntax-w"> </span>"Doe") <span class="devsite-syntax-w"> </span>_users.add(user1) <span class="devsite-syntax-w"> </span>_users.add(user2) <span class="devsite-syntax-w"> </span>_users.add(user3) <span class="devsite-syntax-w"> </span>} } </code></pre></devsite-code> <p>The <a href="https://kotlinlang.org/api/latest/jvm/stdlib/index.html" target="_blank">Kotlin Standard Library</a> uses extension functions to extend the functionality of several Java APIs; a lot of the functionalities on <code translate="no" dir="ltr">Iterable</code> and <code translate="no" dir="ltr">Collection</code> are implemented as extension functions. For example, the <code translate="no" dir="ltr">map</code> function we used in a previous step is an extension function on <code translate="no" dir="ltr">Iterable</code>.</p> </google-codelab-step> <google-codelab-step label="Scope functions: let, apply, with, run, also" duration="5" step="10"> <h2 class="step-title" id="10" data-text="Scope functions: let, apply, with, run, also" tabindex="-1"> 11. Scope functions: let, apply, with, run, also </h2> <p>In our <code translate="no" dir="ltr">Repository</code> class code, we are adding several <code translate="no" dir="ltr">User</code> objects to the <code translate="no" dir="ltr">_users</code> list. These calls can be made more idiomatic with the help of Kotlin scope functions.</p> <p>To execute code only in the context of a specific object, without needing to access the object based on its name, Kotlin offers 5 scope functions: <code translate="no" dir="ltr">let</code>, <code translate="no" dir="ltr">apply</code>, <code translate="no" dir="ltr">with</code>, <code translate="no" dir="ltr">run</code> and <code translate="no" dir="ltr">also</code>. These functions make your code easier to read and more concise. All scope functions have a receiver (<code translate="no" dir="ltr">this</code>), may have an argument (<code translate="no" dir="ltr">it</code>) and may return a value.</p> <p>Here&#39;s a handy cheat sheet to help you remember when to use each function:</p> <p class="image-container"><img alt="6b9283d411fb6e7b.png" style="width: 624.00px" src="/static/codelabs/java-to-kotlin/img/6b9283d411fb6e7b.png" srcset="https://developer.android.com/static/codelabs/java-to-kotlin/img/6b9283d411fb6e7b_36.png 36w,https://developer.android.com/static/codelabs/java-to-kotlin/img/6b9283d411fb6e7b_48.png 48w,https://developer.android.com/static/codelabs/java-to-kotlin/img/6b9283d411fb6e7b_72.png 72w,https://developer.android.com/static/codelabs/java-to-kotlin/img/6b9283d411fb6e7b_96.png 96w,https://developer.android.com/static/codelabs/java-to-kotlin/img/6b9283d411fb6e7b_480.png 480w,https://developer.android.com/static/codelabs/java-to-kotlin/img/6b9283d411fb6e7b_720.png 720w,https://developer.android.com/static/codelabs/java-to-kotlin/img/6b9283d411fb6e7b_856.png 856w,https://developer.android.com/static/codelabs/java-to-kotlin/img/6b9283d411fb6e7b_960.png 960w,https://developer.android.com/static/codelabs/java-to-kotlin/img/6b9283d411fb6e7b_1440.png 1440w,https://developer.android.com/static/codelabs/java-to-kotlin/img/6b9283d411fb6e7b_1920.png 1920w,https://developer.android.com/static/codelabs/java-to-kotlin/img/6b9283d411fb6e7b_2880.png 2880w" sizes="(max-width: 840px) 100vw, 856px"></p> <aside class="special"><p>Download the scope functions cheat sheet from <a href="https://medium.com/androiddevelopers/kotlin-standard-functions-cheat-sheet-27f032dd4326" target="_blank">here</a>.</p> </aside> <p>Since we&#39;re configuring our <code translate="no" dir="ltr">_users</code> object in our <code translate="no" dir="ltr">Repository</code>, we can make the code more idiomatic by using the <code translate="no" dir="ltr">apply</code> function:</p> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="scdoc"><code translate="no" dir="ltr">init { val user1 = User("Jane", "") val user2 = User("John", null) val user3 = User("Anne", "Doe") _users.apply { // this == _users add(user1) add(user2) add(user3) } } </code></pre></devsite-code> <aside class="special"><p>Find out more about scope functions from the <a href="https://kotlinlang.org/docs/reference/scope-functions.html" target="_blank">official documentation</a>.</p> </aside> </google-codelab-step> <google-codelab-step label="Wrap up" duration="1" step="11"> <h2 class="step-title" id="11" data-text="Wrap up" tabindex="-1"> 12. Wrap up </h2> <p>In this codelab, we covered the basics you need to start converting your code from Java to Kotlin. This conversion is independent of your development platform and helps to ensure that the code you write is idiomatic Kotlin.</p> <p>Idiomatic Kotlin makes writing code short and sweet. With all the features Kotlin provides, there are so many ways to make your code safer, more concise, and more readable. For example, we can even optimize our <code translate="no" dir="ltr">Repository</code> class by instantiating the <code translate="no" dir="ltr">_users</code> list with users directly in the declaration, getting rid of the <code translate="no" dir="ltr">init</code> block:</p> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="Text only"><code translate="no" dir="ltr">private val users = mutableListOf(User("Jane", ""), User("John", null), User("Anne", "Doe")) </code></pre></devsite-code> <p>We covered a large array of topics, from handling nullability, singletons, Strings, and collections to topics like extension functions, top-level functions, properties, and scope functions. We went from two Java classes to two Kotlin ones that now look like this:</p> <h3 is-upgraded id="user.kt" data-text="User.kt" tabindex="-1"><strong>User.kt</strong></h3> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="GDScript"><code translate="no" dir="ltr"><span class="devsite-syntax-n">data</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">class</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">User</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-k">var</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">firstName</span><span class="devsite-syntax-p">:</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nb devsite-syntax-nb-Type">String</span><span class="devsite-syntax-err">?</span><span class="devsite-syntax-p">,</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">var</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">lastName</span><span class="devsite-syntax-p">:</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nb devsite-syntax-nb-Type">String</span><span class="devsite-syntax-err">?</span><span class="devsite-syntax-p">)</span> </code></pre></devsite-code> <h3 is-upgraded id="repository.kt" data-text="Repository.kt" tabindex="-1"><strong>Repository.kt</strong></h3> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="Scalate Server Page"><code translate="no" dir="ltr">val<span class="devsite-syntax-w"> </span>User.formattedName:<span class="devsite-syntax-w"> </span>String <span class="devsite-syntax-w"> </span>get()<span class="devsite-syntax-w"> </span>{ <span class="devsite-syntax-w"> </span>return<span class="devsite-syntax-w"> </span>if<span class="devsite-syntax-w"> </span>(lastName<span class="devsite-syntax-w"> </span>!=<span class="devsite-syntax-w"> </span>null)<span class="devsite-syntax-w"> </span>{ <span class="devsite-syntax-w"> </span>if<span class="devsite-syntax-w"> </span>(firstName<span class="devsite-syntax-w"> </span>!=<span class="devsite-syntax-w"> </span>null)<span class="devsite-syntax-w"> </span>{ <span class="devsite-syntax-w"> </span>"$firstName<span class="devsite-syntax-w"> </span>$lastName" <span class="devsite-syntax-w"> </span>}<span class="devsite-syntax-w"> </span>else<span class="devsite-syntax-w"> </span>{ <span class="devsite-syntax-w"> </span>lastName<span class="devsite-syntax-w"> </span>?:<span class="devsite-syntax-w"> </span>"Unknown" <span class="devsite-syntax-w"> </span>} <span class="devsite-syntax-w"> </span>}<span class="devsite-syntax-w"> </span>else<span class="devsite-syntax-w"> </span>{ <span class="devsite-syntax-w"> </span>firstName<span class="devsite-syntax-w"> </span>?:<span class="devsite-syntax-w"> </span>"Unknown" <span class="devsite-syntax-w"> </span>} <span class="devsite-syntax-w"> </span>} object<span class="devsite-syntax-w"> </span>Repository<span class="devsite-syntax-w"> </span>{ <span class="devsite-syntax-w"> </span>private<span class="devsite-syntax-w"> </span>val<span class="devsite-syntax-w"> </span>_users<span class="devsite-syntax-w"> </span>=<span class="devsite-syntax-w"> </span>mutableListOf(User("Jane",<span class="devsite-syntax-w"> </span>""),<span class="devsite-syntax-w"> </span>User("John",<span class="devsite-syntax-w"> </span>null),<span class="devsite-syntax-w"> </span>User("Anne",<span class="devsite-syntax-w"> </span>"Doe")) <span class="devsite-syntax-w"> </span>val<span class="devsite-syntax-w"> </span>users:<span class="devsite-syntax-w"> </span>List&lt;User&gt; <span class="devsite-syntax-w"> </span>get()<span class="devsite-syntax-w"> </span>=<span class="devsite-syntax-w"> </span>_users <span class="devsite-syntax-w"> </span>val<span class="devsite-syntax-w"> </span>formattedUserNames:<span class="devsite-syntax-w"> </span>List&lt;String&gt; <span class="devsite-syntax-w"> </span>get()<span class="devsite-syntax-w"> </span>=<span class="devsite-syntax-w"> </span>_users.map<span class="devsite-syntax-w"> </span>{<span class="devsite-syntax-w"> </span>user<span class="devsite-syntax-w"> </span>-&gt;<span class="devsite-syntax-w"> </span>user.formattedName<span class="devsite-syntax-w"> </span>} } </code></pre></devsite-code> <p>Here&#39;s a TL;DR of the Java functionalities and their mapping to Kotlin:</p> <table class="vertical-rules"> <tr><td colspan="1" rowspan="1"><p><strong>Java</strong></p> </td><td colspan="1" rowspan="1"><p><strong>Kotlin</strong></p> </td></tr> <tr><td colspan="1" rowspan="1"><p><code translate="no" dir="ltr">final</code> object</p> </td><td colspan="1" rowspan="1"><p><code translate="no" dir="ltr">val</code> object</p> </td></tr> <tr><td colspan="1" rowspan="1"><p><code translate="no" dir="ltr">equals()</code></p> </td><td colspan="1" rowspan="1"><p><code translate="no" dir="ltr">==</code></p> </td></tr> <tr><td colspan="1" rowspan="1"><p><code translate="no" dir="ltr">==</code></p> </td><td colspan="1" rowspan="1"><p><code translate="no" dir="ltr">===</code></p> </td></tr> <tr><td colspan="1" rowspan="1"><p>Class that just holds data</p> </td><td colspan="1" rowspan="1"><p><code translate="no" dir="ltr">data</code> class</p> </td></tr> <tr><td colspan="1" rowspan="1"><p>Initialization in the constructor</p> </td><td colspan="1" rowspan="1"><p>Initialization in the <code translate="no" dir="ltr">init</code> block</p> </td></tr> <tr><td colspan="1" rowspan="1"><p><code translate="no" dir="ltr">static</code> fields and functions</p> </td><td colspan="1" rowspan="1"><p>fields and functions declared in a <code translate="no" dir="ltr">companion object</code></p> </td></tr> <tr><td colspan="1" rowspan="1"><p>Singleton class</p> </td><td colspan="1" rowspan="1"><p><code translate="no" dir="ltr">object</code></p> </td></tr> </table> <aside class="special"><p>Note that one of the benefits of Kotlin is that it&#39;s 100% interoperable with the Java programming language. Call Java-based code from Kotlin, or call Kotlin from Java-based code. You can have as little or as much of Kotlin in your project as you want.</p> </aside> <p>To find out more about Kotlin and how to use it on your platform, check out these resources:</p> <ul> <li><a href="https://play.kotlinlang.org/koans/overview" target="_blank">Kotlin Koans</a></li> <li><a href="https://kotlinlang.org/docs/tutorials/" target="_blank">Kotlin Tutorials</a></li> <li><a href="https://developer.android.com/courses/kotlin-android-fundamentals/overview" target="_blank">Android Kotlin Fundamentals</a></li> <li><a href="https://developer.android.com/courses/kotlin-bootcamp/overview" target="_blank">Kotlin Bootcamp for Programmers</a></li> <li><a href="https://www.coursera.org/learn/kotlin-for-java-developers" target="_blank">Kotlin for Java developers</a> - free course in Audit mode</li> </ul> </google-codelab-step> </google-codelab> </div> <div class="devsite-floating-action-buttons"> </div> </article> <devsite-content-footer class="nocontent"> <p>Except as otherwise noted, the content of this page is licensed under the <a href="https://creativecommons.org/licenses/by/4.0/">Creative Commons Attribution 4.0 License</a>, and code samples are licensed under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache 2.0 License</a>. For details, see the <a href="https://developers.google.com/site-policies">Google Developers Site Policies</a>. Java is a registered trademark of Oracle and/or its affiliates.</p> </devsite-content-footer> <devsite-notification link="https://google.qualtrics.com/jfe/form/SV_cRR9tonbkUQYb5Q?link=dac" link-text="Take survey" message="Please help us improve the Android Developer experience by taking a short survey." > </devsite-notification> <div class="devsite-content-data"> <template class="devsite-content-data-template"> [[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Missing the information I need","missingTheInformationINeed","thumb-down"],["Too complicated / too many steps","tooComplicatedTooManySteps","thumb-down"],["Out of date","outOfDate","thumb-down"],["Samples / code issue","samplesCodeIssue","thumb-down"],["Other","otherDown","thumb-down"]],[],[],[]] </template> </div> </devsite-content> </main> <devsite-footer-promos class="devsite-footer"> <nav class="devsite-footer-promos nocontent" aria-label="Promotions"> <ul class="devsite-footer-promos-list"> <li class="devsite-footer-promo"> <a href="//x.com/AndroidDev" class="devsite-footer-promo-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer X Promo" > <picture> <source class="devsite-dark-theme" srcset="https://developer.android.com/_static/android/images/logo-x_dt.svg" media="(prefers-color-scheme: dark)" loading="lazy" alt="X"> <img class="devsite-footer-promo-icon" src="/_static/android/images/logo-x.svg" loading="lazy" alt="X"> </picture> <span class="devsite-footer-promo-label"> X </span> </a> <div class="devsite-footer-promo-description">Follow @AndroidDev on X</div> </li> <li class="devsite-footer-promo"> <a href="//www.youtube.com/user/androiddevelopers" class="devsite-footer-promo-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer YouTube Promo" > <picture> <source class="devsite-dark-theme" srcset="https://developer.android.com/_static/android/images/logo-youtube_dt.svg" media="(prefers-color-scheme: dark)" loading="lazy" alt="YouTube"> <img class="devsite-footer-promo-icon" src="//www.gstatic.com/images/icons/material/product/2x/youtube_48dp.png" loading="lazy" alt="YouTube"> </picture> <span class="devsite-footer-promo-label"> YouTube </span> </a> <div class="devsite-footer-promo-description">Check out Android Developers on YouTube</div> </li> <li class="devsite-footer-promo"> <a href="//www.linkedin.com/showcase/androiddev" class="devsite-footer-promo-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer LinkedIn Promo" > <picture> <source class="devsite-dark-theme" srcset="https://developer.android.com/_static/android/images/logo-linkedin_dt.svg" media="(prefers-color-scheme: dark)" loading="lazy" alt="LinkedIn"> <img class="devsite-footer-promo-icon" src="/_static/android/images/logo-linkedin.svg" loading="lazy" alt="LinkedIn"> </picture> <span class="devsite-footer-promo-label"> LinkedIn </span> </a> <div class="devsite-footer-promo-description">Connect with the Android Developers community on LinkedIn</div> </li> </ul> </nav> </devsite-footer-promos> <devsite-footer-linkboxes class="devsite-footer"> <nav class="devsite-footer-linkboxes nocontent" aria-label="Footer links"> <ul class="devsite-footer-linkboxes-list"> <li class="devsite-footer-linkbox "> <h3 class="devsite-footer-linkbox-heading no-link">More Android</h3> <ul class="devsite-footer-linkbox-list"> <li class="devsite-footer-linkbox-item"> <a href="//www.android.com" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 1)" > Android </a> </li> <li class="devsite-footer-linkbox-item"> <a href="//www.android.com/enterprise/" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 2)" > Android for Enterprise </a> </li> <li class="devsite-footer-linkbox-item"> <a href="//www.android.com/security-center/" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 3)" > Security </a> </li> <li class="devsite-footer-linkbox-item"> <a href="//source.android.com" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 4)" > Source </a> </li> <li class="devsite-footer-linkbox-item"> <a href="/news" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 5)" > News </a> </li> <li class="devsite-footer-linkbox-item"> <a href="//android-developers.googleblog.com/" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 6)" > Blog </a> </li> <li class="devsite-footer-linkbox-item"> <a href="/podcasts" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 7)" > Podcasts </a> </li> </ul> </li> <li class="devsite-footer-linkbox "> <h3 class="devsite-footer-linkbox-heading no-link">Discover</h3> <ul class="devsite-footer-linkbox-list"> <li class="devsite-footer-linkbox-item"> <a href="/games" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 1)" > Gaming </a> </li> <li class="devsite-footer-linkbox-item"> <a href="/ml" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 2)" > Machine Learning </a> </li> <li class="devsite-footer-linkbox-item"> <a href="/health-and-fitness" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 3)" > Health & Fitness </a> </li> <li class="devsite-footer-linkbox-item"> <a href="/media" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 4)" > Camera & Media </a> </li> <li class="devsite-footer-linkbox-item"> <a href="/privacy" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 5)" > Privacy </a> </li> <li class="devsite-footer-linkbox-item"> <a href="/training/connectivity/5g" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 6)" > 5G </a> </li> </ul> </li> <li class="devsite-footer-linkbox "> <h3 class="devsite-footer-linkbox-heading no-link">Android Devices</h3> <ul class="devsite-footer-linkbox-list"> <li class="devsite-footer-linkbox-item"> <a href="/large-screens" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 1)" > Large screens </a> </li> <li class="devsite-footer-linkbox-item"> <a href="/wear" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 2)" > Wear OS </a> </li> <li class="devsite-footer-linkbox-item"> <a href="/chrome-os" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 3)" > ChromeOS devices </a> </li> <li class="devsite-footer-linkbox-item"> <a href="/cars" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 4)" > Android for cars </a> </li> <li class="devsite-footer-linkbox-item"> <a href="/tv" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 5)" > Android TV </a> </li> </ul> </li> <li class="devsite-footer-linkbox "> <h3 class="devsite-footer-linkbox-heading no-link">Releases</h3> <ul class="devsite-footer-linkbox-list"> <li class="devsite-footer-linkbox-item"> <a href="/about/versions/15" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 1)" > Android 15 </a> </li> <li class="devsite-footer-linkbox-item"> <a href="/about/versions/14" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 2)" > Android 14 </a> </li> <li class="devsite-footer-linkbox-item"> <a href="/about/versions/13" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 3)" > Android 13 </a> </li> <li class="devsite-footer-linkbox-item"> <a href="/about/versions/12" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 4)" > Android 12 </a> </li> <li class="devsite-footer-linkbox-item"> <a href="/about/versions/11" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 5)" > Android 11 </a> </li> <li class="devsite-footer-linkbox-item"> <a href="/about/versions/10" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 6)" > Android 10 </a> </li> <li class="devsite-footer-linkbox-item"> <a href="/about/versions/pie" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 7)" > Pie </a> </li> </ul> </li> <li class="devsite-footer-linkbox "> <h3 class="devsite-footer-linkbox-heading no-link">Documentation and Downloads</h3> <ul class="devsite-footer-linkbox-list"> <li class="devsite-footer-linkbox-item"> <a href="/studio/intro" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 1)" > Android Studio guide </a> </li> <li class="devsite-footer-linkbox-item"> <a href="/guide" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 2)" > Developers guides </a> </li> <li class="devsite-footer-linkbox-item"> <a href="/reference" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 3)" > API reference </a> </li> <li class="devsite-footer-linkbox-item"> <a href="/studio" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 4)" > Download Studio </a> </li> <li class="devsite-footer-linkbox-item"> <a href="/ndk" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 5)" > Android NDK </a> </li> </ul> </li> <li class="devsite-footer-linkbox "> <h3 class="devsite-footer-linkbox-heading no-link">Support</h3> <ul class="devsite-footer-linkbox-list"> <li class="devsite-footer-linkbox-item"> <a href="//issuetracker.google.com/issues/new?component=190923&amp;template=841312" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 1)" > Report platform bug </a> </li> <li class="devsite-footer-linkbox-item"> <a href="//issuetracker.google.com/issues/new?component=192697" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 2)" > Report documentation bug </a> </li> <li class="devsite-footer-linkbox-item"> <a href="//support.google.com/googleplay/android-developer" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 3)" > Google Play support </a> </li> <li class="devsite-footer-linkbox-item"> <a href="https://g.co/userresearch/androiddeveloperfooter" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 4)" > Join research studies </a> </li> </ul> </li> </ul> </nav> </devsite-footer-linkboxes> <devsite-footer-utility class="devsite-footer"> <div class="devsite-footer-utility nocontent"> <nav class="devsite-footer-sites" aria-label="Other Google Developers websites"> <a href="https://developers.google.com/" class="devsite-footer-sites-logo-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Google Developers Link"> <picture> <source srcset="https://www.gstatic.com/devrel-devsite/prod/v38a693baeb774512feb42f10aac8f755d8791ed41119b5be7a531f8e16f8279f/android/images/lockup-google-for-developers-dark-theme.svg" media="(prefers-color-scheme: none)" class="devsite-dark-theme" loading="lazy" alt="Google Developers"> <img class="devsite-footer-sites-logo" src="https://www.gstatic.com/devrel-devsite/prod/v38a693baeb774512feb42f10aac8f755d8791ed41119b5be7a531f8e16f8279f/android/images/lockup-google-for-developers.svg" loading="lazy" alt="Google Developers"> </picture> </a> <ul class="devsite-footer-sites-list"> <li class="devsite-footer-sites-item"> <a href="//developer.android.com" class="devsite-footer-sites-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Android Link" > Android </a> </li> <li class="devsite-footer-sites-item"> <a href="//developer.chrome.com/home" class="devsite-footer-sites-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Chrome Link" > Chrome </a> </li> <li class="devsite-footer-sites-item"> <a href="//firebase.google.com" class="devsite-footer-sites-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Firebase Link" > Firebase </a> </li> <li class="devsite-footer-sites-item"> <a href="//cloud.google.com" class="devsite-footer-sites-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Google Cloud Platform Link" > Google Cloud Platform </a> </li> <li class="devsite-footer-sites-item"> <a href="//developers.google.com/products/" class="devsite-footer-sites-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer All products Link" > All products </a> </li> </ul> </nav> <nav class="devsite-footer-utility-links" aria-label="Utility links"> <ul class="devsite-footer-utility-list"> <li class="devsite-footer-utility-item "> <a class="devsite-footer-utility-link gc-analytics-event" href="//policies.google.com/privacy" data-category="Site-Wide Custom Events" data-label="Footer Privacy link" > Privacy </a> </li> <li class="devsite-footer-utility-item "> <a class="devsite-footer-utility-link gc-analytics-event" href="/license" data-category="Site-Wide Custom Events" data-label="Footer License link" > License </a> </li> <li class="devsite-footer-utility-item "> <a class="devsite-footer-utility-link gc-analytics-event" href="/distribute/marketing-tools/brand-guidelines" data-category="Site-Wide Custom Events" data-label="Footer Brand guidelines link" > Brand guidelines </a> </li> <li class="devsite-footer-utility-item glue-cookie-notification-bar-control"> <a class="devsite-footer-utility-link gc-analytics-event" href="#" data-category="Site-Wide Custom Events" data-label="Footer Manage cookies link" aria-hidden="true" > Manage cookies </a> </li> <li class="devsite-footer-utility-item devsite-footer-utility-button"> <span class="devsite-footer-utility-description">Get news and tips by email</span> <a class="devsite-footer-utility-link gc-analytics-event" href="/updates" data-category="Site-Wide Custom Events" data-label="Footer Subscribe link" > Subscribe </a> </li> </ul> <devsite-language-selector> <ul role="presentation"> <li role="presentation"> <a role="menuitem" lang="en" >English</a> </li> <li role="presentation"> <a role="menuitem" lang="de" >Deutsch</a> </li> <li role="presentation"> <a role="menuitem" lang="es_419" >Español – América Latina</a> </li> <li role="presentation"> <a role="menuitem" lang="fr" >Français</a> </li> <li role="presentation"> <a role="menuitem" lang="id" >Indonesia</a> </li> <li role="presentation"> <a role="menuitem" lang="it" >Italiano</a> </li> <li role="presentation"> <a role="menuitem" lang="pl" >Polski</a> </li> <li role="presentation"> <a role="menuitem" lang="pt_br" >Português – Brasil</a> </li> <li role="presentation"> <a role="menuitem" lang="vi" >Tiếng Việt</a> </li> <li role="presentation"> <a role="menuitem" lang="tr" >Türkçe</a> </li> <li role="presentation"> <a role="menuitem" lang="ru" >Русский</a> </li> <li role="presentation"> <a role="menuitem" lang="he" >עברית</a> </li> <li role="presentation"> <a role="menuitem" lang="ar" >العربيّة</a> </li> <li role="presentation"> <a role="menuitem" lang="fa" >فارسی</a> </li> <li role="presentation"> <a role="menuitem" lang="hi" >हिंदी</a> </li> <li role="presentation"> <a role="menuitem" lang="bn" >বাংলা</a> </li> <li role="presentation"> <a role="menuitem" lang="th" >ภาษาไทย</a> </li> <li role="presentation"> <a role="menuitem" lang="zh_cn" >中文 – 简体</a> </li> <li role="presentation"> <a role="menuitem" lang="zh_tw" >中文 – 繁體</a> </li> <li role="presentation"> <a role="menuitem" lang="ja" >日本語</a> </li> <li role="presentation"> <a role="menuitem" lang="ko" >한국어</a> </li> </ul> </devsite-language-selector> </nav> </div> </devsite-footer-utility> <devsite-panel></devsite-panel> </section></section> <devsite-sitemask></devsite-sitemask> <devsite-snackbar></devsite-snackbar> <devsite-tooltip ></devsite-tooltip> <devsite-heading-link></devsite-heading-link> <devsite-analytics> <script type="application/json" analytics>[]</script> <script type="application/json" tag-management>{&#34;at&#34;: &#34;True&#34;, &#34;ga4&#34;: [{&#34;id&#34;: &#34;G-QFRN08RN6E&#34;, &#34;purpose&#34;: 0}], &#34;ga4p&#34;: [{&#34;id&#34;: &#34;G-QFRN08RN6E&#34;, &#34;purpose&#34;: 0}], &#34;gtm&#34;: [], &#34;parameters&#34;: {&#34;internalUser&#34;: &#34;False&#34;, &#34;language&#34;: {&#34;machineTranslated&#34;: &#34;False&#34;, &#34;requested&#34;: &#34;en&#34;, &#34;served&#34;: &#34;en&#34;}, &#34;pageType&#34;: &#34;codelab&#34;, &#34;projectName&#34;: null, &#34;signedIn&#34;: &#34;False&#34;, &#34;tenant&#34;: &#34;android&#34;, &#34;recommendations&#34;: {&#34;sourcePage&#34;: &#34;&#34;, &#34;sourceType&#34;: 0, &#34;sourceRank&#34;: 0, &#34;sourceIdenticalDescriptions&#34;: 0, &#34;sourceTitleWords&#34;: 0, &#34;sourceDescriptionWords&#34;: 0, &#34;experiment&#34;: &#34;&#34;}, &#34;experiment&#34;: {&#34;ids&#34;: &#34;&#34;}}}</script> </devsite-analytics> <devsite-badger></devsite-badger> <android-fully-clickable target=" .android-case-study .devsite-landing-row-item, .android-grouped-resources .devsite-landing-row-item, .android-grouped-resources-contained--primary .devsite-landing-row-item, .android-grouped-resources-contained--secondary .devsite-landing-row-item, .android-grouped-resources-contained--tertiary .devsite-landing-row-item, .android-grouped-resources-uncontained--primary .devsite-landing-row-item, .android-grouped-resources-uncontained--secondary .devsite-landing-row-item, .android-grouped-resources-uncontained--tertiary .devsite-landing-row-item, .android-guide-cards .devsite-landing-row-item, .android-illustrated-resources-index .devsite-landing-row-item, .android-illustrated-resources-primary .devsite-landing-row-item, .android-illustrated-resources-secondary .devsite-landing-row-item, .android-illustrated-resources-secondary-small .devsite-landing-row-item, .android-illustrated-resources-tertiary .devsite-landing-row-item, .android-illustrated-resources-tertiary-small .devsite-landing-row-item, .android-promo .devsite-landing-row-item, .android-quick-link, .android-samples .devsite-card-wrapper, .fully-clickable" watch=".android-samples, devsite-content"></android-fully-clickable> <script nonce="5W15LYDRuda2sWF6IwFbFQUaYvOfFu"> (function(d,e,v,s,i,t,E){d['GoogleDevelopersObject']=i; t=e.createElement(v);t.async=1;t.src=s;E=e.getElementsByTagName(v)[0]; E.parentNode.insertBefore(t,E);})(window, document, 'script', 'https://www.gstatic.com/devrel-devsite/prod/v38a693baeb774512feb42f10aac8f755d8791ed41119b5be7a531f8e16f8279f/android/js/app_loader.js', '[3,"en",null,"/js/devsite_app_module.js","https://www.gstatic.com/devrel-devsite/prod/v38a693baeb774512feb42f10aac8f755d8791ed41119b5be7a531f8e16f8279f","https://www.gstatic.com/devrel-devsite/prod/v38a693baeb774512feb42f10aac8f755d8791ed41119b5be7a531f8e16f8279f/android","https://android-dot-devsite-v2-prod.appspot.com",1,null,["/_pwa/android/manifest.json","https://www.gstatic.com/devrel-devsite/prod/v38a693baeb774512feb42f10aac8f755d8791ed41119b5be7a531f8e16f8279f/images/video-placeholder.svg","https://www.gstatic.com/devrel-devsite/prod/v38a693baeb774512feb42f10aac8f755d8791ed41119b5be7a531f8e16f8279f/android/images/favicon.svg","https://www.gstatic.com/devrel-devsite/prod/v38a693baeb774512feb42f10aac8f755d8791ed41119b5be7a531f8e16f8279f/android/images/lockup.svg","https://fonts.googleapis.com/css?family=Google+Sans:400,500,600,700|Google+Sans+Text:400,400italic,500,500italic,600,600italic,700,700italic|Roboto+Mono:400,500,700&display=swap"],1,null,[1,6,8,12,14,17,21,25,50,52,63,70,75,76,80,87,91,92,93,97,98,100,101,102,103,104,105,107,108,109,110,112,113,117,118,120,122,124,125,126,127,129,130,131,132,133,134,135,136,138,140,141,147,148,149,151,152,156,157,158,159,161,163,164,168,169,170,179,180,182,183,186,191,193,196],"AIzaSyAP-jjEJBzmIyKR4F-3XITp8yM9T1gEEI8","AIzaSyB6xiKGDR5O3Ak2okS4rLkauxGUG7XP0hg","developer.android.com","AIzaSyAQk0fBONSGUqCNznf6Krs82Ap1-NV6J4o","AIzaSyCCxcqdrZ_7QMeLCRY20bh_SXdAYqy70KY",null,null,null,["Profiles__enable_complete_playlist_endpoint","Profiles__enable_profile_collections","DevPro__enable_developer_subscriptions","Profiles__enable_public_developer_profiles","Cloud__enable_cloudx_ping","CloudShell__cloud_shell_button","MiscFeatureFlags__enable_project_variables","Analytics__enable_clearcut_logging","CloudShell__cloud_code_overflow_menu","TpcFeatures__enable_mirror_tenant_redirects","MiscFeatureFlags__emergency_css","Profiles__enable_developer_profiles_callout","MiscFeatureFlags__enable_firebase_utm","DevPro__enable_cloud_innovators_plus","EngEduTelemetry__enable_engedu_telemetry","Search__enable_suggestions_from_borg","Search__enable_ai_eligibility_checks","MiscFeatureFlags__developers_footer_dark_image","Cloud__enable_cloud_dlp_service","Profiles__enable_join_program_group_endpoint","Cloud__enable_cloud_facet_chat","Search__enable_dynamic_content_confidential_banner","Search__enable_ai_search_summaries","Profiles__enable_awarding_url","Cloud__enable_llm_concierge_chat","Cloud__enable_cloudx_experiment_ids","Search__enable_page_map","Cloud__enable_legacy_calculator_redirect","MiscFeatureFlags__enable_view_transitions","Cloud__enable_cloud_shell","Profiles__enable_release_notes_notifications","Profiles__enable_completequiz_endpoint","BookNav__enable_tenant_cache_key","Experiments__reqs_query_experiments","MiscFeatureFlags__enable_explain_this_code","Profiles__enable_completecodelab_endpoint","Cloud__enable_cloud_shell_fte_user_flow","MiscFeatureFlags__enable_dark_theme","Concierge__enable_pushui","Profiles__enable_page_saving","Profiles__require_profile_eligibility_for_signin","TpcFeatures__enable_unmirrored_page_left_nav","Profiles__enable_stripe_subscription_management","Significatio__enable_by_tenant","Cloud__enable_free_trial_server_call","MiscFeatureFlags__enable_variable_operator","MiscFeatureFlags__developers_footer_image","Profiles__enable_recognition_badges","Profiles__enable_dashboard_curated_recommendations"],null,null,"AIzaSyBLEMok-5suZ67qRPzx0qUtbnLmyT_kCVE","https://developerscontentserving-pa.googleapis.com","AIzaSyCM4QpTRSqP5qI4Dvjt4OAScIN8sOUlO-k","https://developerscontentsearch-pa.googleapis.com",2,4,null,"https://developerprofiles-pa.googleapis.com",[3,"android","Android Developers","developer.android.com",null,"android-dot-devsite-v2-prod.appspot.com",null,null,[null,1,null,null,null,null,null,null,null,null,null,[1],null,null,null,null,null,null,[1],[1,null,null,[1,20],"/recommendations"],null,null,null,[1,null,1],[1,1,null,1,1]],null,[18,null,null,null,null,null,"/images/lockup.svg","/images/touchicon-180.png",null,null,null,null,null,null,null,null,null,null,null,null,null,2,null,null,null,"/images/lockup-dark-theme.svg",[]],[],null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,[6,1,14,15,20,22,23,28,29,37,43],null,[[null,null,1],[1,1]],[[null,null,null,null,null,null,null,[["G-QFRN08RN6E"],null,null,[["G-QFRN08RN6E",1]]],null,null,null,null,1],null,[[1,1],[2,2]]],null,4,null,null,null,null,null,null,null,null,null,null,null,null,null,"android.devsite.google"],null,"pk_live_5170syrHvgGVmSx9sBrnWtA5luvk9BwnVcvIi7HizpwauFG96WedXsuXh790rtij9AmGllqPtMLfhe2RSwD6Pn38V00uBCydV4m",1]') </script> <devsite-a11y-announce></devsite-a11y-announce> </body> </html>

Pages: 1 2 3 4 5 6 7 8 9 10