Site icon C1CTech

Kotlin Null Safety

<p>This tutorial is about <span style&equals;"color&colon; &num;000000&semi;"><strong>Null Safety<&sol;strong><&sol;span> in Kotlin&period;<&sol;p>&NewLine;<p><span style&equals;"color&colon; &num;008000&semi;"><strong>Null Safety<&sol;strong><&sol;span> in Kotlin is to eliminate the risk of occurrence of <strong><span style&equals;"color&colon; &num;008000&semi;">NullPointerException<&sol;span><&sol;strong> from code&period;<&sol;p>&NewLine;<p class&equals;"p1">One of the most common pitfalls in many programming languages&comma; including Java&comma; is that accessing a member of a null reference will result in a null reference exception&period; In Java this would be the equivalent of a <strong><span style&equals;"color&colon; &num;0000ff&semi;">NullPointerException or NPE<&sol;span><&sol;strong>&period;<&sol;p>&NewLine;<p class&equals;"p1">Let&&num;8217&semi;s understand with simple example in Java where <strong>NullPointerException<&sol;strong> occurs&colon;<&sol;p>&NewLine;<p><strong><span style&equals;"color&colon; &num;0000ff&semi;">Example&colon;<&sol;span><&sol;strong><&sol;p>&NewLine;<pre>class Student &lbrace;&NewLine; public static void main&lpar;String&lbrack;&rsqb; args&rpar; &lbrace;&NewLine; String name &equals; null&semi;&NewLine; System&period;out&period;println&lpar;"Student name &colon; " &plus; name&rpar;&semi;&NewLine; System&period;out&period;println&lpar;"Student name &lpar;Uppercase&rpar;&colon; " &plus; name&period;toUpperCase&lpar;&rpar;&rpar;&semi;&NewLine; &rcub;&NewLine;&rcub;<&sol;pre>&NewLine;<p><strong><span style&equals;"color&colon; &num;0000ff&semi;">Output&colon;<&sol;span><&sol;strong><&sol;p>&NewLine;<pre>Student name &colon; null&NewLine;Exception in thread "main" java&period;lang&period;NullPointerException&NewLine;at Student&period;main&lpar;Exp&period;java&colon;6&rpar;<&sol;pre>&NewLine;<p>Kotlin&&num;8217&semi;s comes with <strong>null safety<&sol;strong> to eliminate <strong>NullPointerException&&num;8217&semi;s<&sol;strong> from our code&period;<&sol;p>&NewLine;<h4 class&equals;"p1"><span style&equals;"color&colon; &num;000080&semi;"><b>Nullable and Non-Null References<&sol;b><&sol;span><&sol;h4>&NewLine;<p class&equals;"p2">In Kotlin&comma; the type system differentiates between two types of references&colon;<&sol;p>&NewLine;<ol class&equals;"ol1">&NewLine;<li class&equals;"li2"><span style&equals;"color&colon; &num;0000ff&semi;"><b>Nullable Reference&colon;<&sol;b><&sol;span> These references <strong><span style&equals;"color&colon; &num;008000&semi;">can hold<&sol;span><&sol;strong> <span style&equals;"color&colon; &num;008000&semi;"><strong>null<&sol;strong><&sol;span> values&period;<&sol;li>&NewLine;<li class&equals;"li2"><span style&equals;"color&colon; &num;0000ff&semi;"><b>Non-Null Reference&colon;<&sol;b><&sol;span> These references <strong><span style&equals;"color&colon; &num;008000&semi;">can&&num;8217&semi;t hold<&sol;span> <span style&equals;"color&colon; &num;008000&semi;">null<&sol;span><&sol;strong> values&period;<&sol;li>&NewLine;<&sol;ol>&NewLine;<p class&equals;"p1">In Kotlin&comma; all variables are non-nullable by default&period; We cannot assign a <strong><span style&equals;"color&colon; &num;008000&semi;"><i>null<&sol;i><&sol;span><&sol;strong> value to a variable because it’ll throw a compilation error&lpar;<strong>NPE<&sol;strong>&rpar;&colon;<&sol;p>&NewLine;<p class&equals;"p2"><span style&equals;"color&colon; &num;0000ff&semi;"><strong>Example&colon;<&sol;strong><&sol;span><&sol;p>&NewLine;<pre>fun main&lpar;&rpar; &lbrace;&NewLine; var name&colon;String &equals; "Arun"&NewLine; var name&colon;String &equals; null <strong><span style&equals;"color&colon; &num;008000&semi;">&sol;&sol; COMPILATION ERROR<&sol;span><&sol;strong>&NewLine;&rcub;<&sol;pre>&NewLine;<p><strong><span style&equals;"color&colon; &num;0000ff&semi;">Output&colon;<&sol;span><&sol;strong><&sol;p>&NewLine;<pre>Error&colon;&lpar;6&comma; 27&rpar; Kotlin&colon; Null can not be a value of a non-null type String<&sol;pre>&NewLine;<p class&equals;"p1">Here&comma; by default compiler considers <strong><span style&equals;"color&colon; &num;008000&semi;">name<&sol;span><&sol;strong> variable as a Non-Null reference&period; So&comma; we cannot assign <span style&equals;"color&colon; &num;0000ff&semi;"><strong>null<&sol;strong><&sol;span> to it&period;<&sol;p>&NewLine;<p class&equals;"p1"><strong class&equals;"jg ks">To define a nullable variable&comma; we must append a question mark&lpar;&quest;&rpar; to the type declaration&colon;<&sol;strong><&sol;p>&NewLine;<pre>fun main&lpar;&rpar; &lbrace;&NewLine; var name&colon; String&quest; &equals; null <span style&equals;"color&colon; &num;008000&semi;"><strong> &sol;&sol; NO ERROR<&sol;strong><&sol;span>&NewLine;&rcub;<&sol;pre>&NewLine;<p class&equals;"p1">We can call a method or access a property on a non-nullable variable&period; However&comma; in the case of nullable variables&comma; we need to handle the null case explicitly&period; Otherwise&comma; it will throw a compilation error since Kotlin knows that the variable contains null references&colon;<&sol;p>&NewLine;<pre class&equals;" language-kotlin"><code class&equals;" language-kotlin"><span class&equals;"token keyword">fun<&sol;span> <span class&equals;"token function">main<&sol;span><span class&equals;"token punctuation">&lpar;<&sol;span><span class&equals;"token punctuation">&rpar;<&sol;span> <span class&equals;"token punctuation">&lbrace;<&sol;span>&NewLine; <span class&equals;"token keyword">var<&sol;span> name<span class&equals;"token operator">&colon;<&sol;span>String<span class&equals;"token operator">&quest;<&sol;span> <span class&equals;"token operator">&equals;<&sol;span> <span class&equals;"token string">"Arun"<&sol;span>&NewLine; <span class&equals;"token function">println<&sol;span><span class&equals;"token punctuation">&lpar;<&sol;span>name<span class&equals;"token punctuation">&period;<&sol;span>length<span class&equals;"token punctuation">&rpar;<&sol;span> <strong><span class&equals;"token comment" style&equals;"color&colon; &num;008000&semi;"> &sol;&sol; ERROR<&sol;span><&sol;strong>&NewLine;<span class&equals;"token punctuation">&rcub;<&sol;span><&sol;code><&sol;pre>&NewLine;<p><strong><span style&equals;"color&colon; &num;0000ff&semi;">Output&colon;<&sol;span><&sol;strong><&sol;p>&NewLine;<pre>Error&colon;&lpar;7&comma; 21&rpar; Kotlin&colon; Only safe &lpar;&quest;&period;&rpar; or non-null asserted &lpar;&excl;&excl;&period;&rpar; calls are allowed on a nullable receiver of type String&quest;<&sol;pre>&NewLine;<p>Here compiler is not allowing us to find length of the String directly because it may throw Null Pointer Exception&period;<&sol;p>&NewLine;<h4 id&equals;"b233" class&equals;"ig ih dt ce ii ij ik il im in io ip iq ir is it iu iv iw ix iy iz ja jb jc jd eq"><span style&equals;"color&colon; &num;000080&semi;"><strong class&equals;"ax">Working With Nullable Types<&sol;strong><&sol;span><&sol;h4>&NewLine;<p class&equals;"p1">Let’s look at the different ways how we can handle null references safely in Kotlin&period;<&sol;p>&NewLine;<ul class&equals;"ol1">&NewLine;<li class&equals;"li1"><strong><span style&equals;"color&colon; &num;0000ff&semi;">Check null in conditions<&sol;span><&sol;strong><&sol;li>&NewLine;<li class&equals;"li1"><strong><span style&equals;"color&colon; &num;0000ff&semi;">Safe calls<&sol;span><&sol;strong><&sol;li>&NewLine;<li class&equals;"li1"><strong><span style&equals;"color&colon; &num;0000ff&semi;">The Elvis operator<&sol;span><&sol;strong><&sol;li>&NewLine;<li class&equals;"li1"><strong><span style&equals;"color&colon; &num;0000ff&semi;">The &excl;&excl; operator<&sol;span><&sol;strong><&sol;li>&NewLine;<&sol;ul>&NewLine;<h4 class&equals;"p2"><span style&equals;"color&colon; &num;000080&semi;"><b>Null <&sol;b><&sol;span><span style&equals;"color&colon; &num;000080&semi;"><b>Check<&sol;b><&sol;span><&sol;h4>&NewLine;<p class&equals;"p1"><strong>We can use the <span style&equals;"color&colon; &num;008000&semi;">if-else<&sol;span> expression to explicitly check for nullable variables&period;<&sol;strong><&sol;p>&NewLine;<p><strong><span style&equals;"color&colon; &num;0000ff&semi;">Example&colon;<&sol;span><&sol;strong><&sol;p>&NewLine;<pre>fun main&lpar;&rpar; &lbrace;&NewLine; var name&colon;String&quest; &equals; "Arun"&NewLine; if &lpar;name &excl;&equals; null&rpar;&NewLine; println&lpar;name&period;length&rpar;&NewLine; else &NewLine; null&NewLine;&rcub;<&sol;pre>&NewLine;<p><strong><span style&equals;"color&colon; &num;0000ff&semi;">Output&colon;<&sol;span><&sol;strong><&sol;p>&NewLine;<pre>4<&sol;pre>&NewLine;<p class&equals;"p1">Now compiler won&&num;8217&semi;t give any error as we have already checked null condition first&period; It is the most basic way to deal with Nullable Reference&period;<&sol;p>&NewLine;<h4 class&equals;"p2"><span style&equals;"color&colon; &num;000080&semi;"><b>Safe Call Operator&lpar;&quest;&period;&rpar;<&sol;b><&sol;span><&sol;h4>&NewLine;<p class&equals;"p1"><strong class&equals;"jg ks">Kotlin has a safe call <span style&equals;"color&colon; &num;008000&semi;">operator&lpar;&quest;&period;&rpar;<&sol;span> to handle null references<&sol;strong>&period;<&sol;p>&NewLine;<&excl;-- WP QUADS Content Ad Plugin v&period; 2&period;0&period;98&period;1 -->&NewLine;<div class&equals;"quads-location quads-ad2" id&equals;"quads-ad2" style&equals;"float&colon;none&semi;margin&colon;0px&semi;">&NewLine;&NewLine;<&sol;div>&NewLine;&NewLine;<p class&equals;"p1">This operator executes any action only when the reference has a non-null value&period; Otherwise&comma; it returns a <span style&equals;"color&colon; &num;008000&semi;"><strong>null<&sol;strong><&sol;span> value&period;<&sol;p>&NewLine;<p>The following expression&colon;<&sol;p>&NewLine;<pre>name&quest;&period;length<&sol;pre>&NewLine;<p>is equivalent to&colon;<&sol;p>&NewLine;<pre>if &lpar;name &excl;&equals; null&rpar;&NewLine; name&period;length&NewLine; else&NewLine; null<&sol;pre>&NewLine;<p><strong><span style&equals;"color&colon; &num;0000ff&semi;">Example&colon;<&sol;span><&sol;strong><&sol;p>&NewLine;<pre>fun main&lpar;&rpar; &lbrace;&NewLine; var name&colon; String&quest; &equals; "Ninja"&NewLine; println&lpar;"Name length&colon; &dollar;&lbrace;name&quest;&period;length&rcub;"&rpar;&NewLine;&NewLine; name &equals; null&NewLine; println&lpar;"Name length&colon; &dollar;&lbrace;name&quest;&period;length&rcub;"&rpar;&NewLine;&rcub;<&sol;pre>&NewLine;<p><strong><span style&equals;"color&colon; &num;0000ff&semi;">Output&colon;<&sol;span><&sol;strong><&sol;p>&NewLine;<pre>Name length&colon; 5&NewLine;Name length&colon; null<&sol;pre>&NewLine;<h4 class&equals;"p1"><span style&equals;"color&colon; &num;000080&semi;"><b>Using let&lpar;&rpar; Method<&sol;b><&sol;span><&sol;h4>&NewLine;<p class&equals;"p2">We can use the <strong><span style&equals;"color&colon; &num;008000&semi;">let&lpar;&rpar;<&sol;span><&sol;strong> method along with the safe call operator to act on a non-nullable variable&colon;<&sol;p>&NewLine;<p><strong><span style&equals;"color&colon; &num;0000ff&semi;">Example&colon;<&sol;span><&sol;strong><&sol;p>&NewLine;<pre>fun main&lpar;args&colon; Array&lt&semi;String&gt&semi;&rpar; &lbrace;&NewLine; val cities&colon; List&lt&semi;String&quest;&gt&semi; &equals; listOf&lpar;"Kolkata"&comma; null&comma; "Mumbai"&comma; "Delhi"&comma; null&comma; "Banglore"&rpar;&NewLine; var newlist&colon; List&lt&semi;String&quest;&gt&semi; &equals; emptyList&lpar;&rpar;&NewLine; for &lpar;city in cities&rpar; &lbrace;&NewLine; city&quest;&period;let &lbrace;&NewLine; newlist &equals; newlist&period;plus&lpar;it&rpar;&NewLine; &rcub;&NewLine; &rcub;&NewLine; println&lpar;newlist&rpar;<&sol;pre>&NewLine;<p><strong><span style&equals;"color&colon; &num;0000ff&semi;">Output&colon;<&sol;span><&sol;strong><&sol;p>&NewLine;<pre>&lbrack;Kolkata&comma; Mumbai&comma; Delhi&comma; Banglore&rsqb;<&sol;pre>&NewLine;<h4 class&equals;"p1"><span style&equals;"color&colon; &num;000080&semi;"><b>Using also&lpar;&rpar; Method<&sol;b><&sol;span><&sol;h4>&NewLine;<p class&equals;"p2">We can use the <strong><span style&equals;"color&colon; &num;008000&semi;">also&lpar;&rpar; <&sol;span><&sol;strong>method to execute additional operations like logging and printing of the non-nullable variables&period; <b>This method can be used in a chain with<span style&equals;"color&colon; &num;008000&semi;"> let&lpar;&rpar; or run&lpar;&rpar; <&sol;span>method<&sol;b>&period;<&sol;p>&NewLine;<p class&equals;"p2">Here&&num;8217&semi;s how we can use also&lpar;&rpar; method along with let&lpar;&rpar; method&colon;<&sol;p>&NewLine;<p><strong><span style&equals;"color&colon; &num;0000ff&semi;">Example&colon;<&sol;span><&sol;strong><&sol;p>&NewLine;<pre>fun main&lpar;args&colon; Array&lt&semi;String&gt&semi;&rpar; &lbrace;&NewLine;&NewLine; val cities&colon; List&lt&semi;String&quest;&gt&semi; &equals; listOf&lpar;"Kolkata"&comma; null&comma; "Mumbai"&comma; "Delhi"&comma; null&comma; "Banglore"&rpar;&NewLine; var newlist&colon; List&lt&semi;String&quest;&gt&semi; &equals; emptyList&lpar;&rpar;&NewLine; &NewLine; for &lpar;city in cities&rpar; &lbrace;&NewLine; city&quest;&period;let &lbrace;&NewLine; newlist &equals; newlist&period;plus&lpar;it&rpar;&NewLine; it&NewLine; &rcub;&quest;&period;also &lbrace; it -&gt&semi; println&lpar;"&dollar;it"&rpar; &rcub;&NewLine; &rcub;&NewLine; println&lpar;newlist&rpar;<&sol;pre>&NewLine;<p><strong><span style&equals;"color&colon; &num;0000ff&semi;">Output&colon;<&sol;span><&sol;strong><&sol;p>&NewLine;<pre>Kolkata&NewLine;Mumbai&NewLine;Delhi&NewLine;Banglore&NewLine;&lbrack;Kolkata&comma; Mumbai&comma; Delhi&comma; Banglore&rsqb;<&sol;pre>&NewLine;<h4 class&equals;"p1"><span style&equals;"color&colon; &num;000080&semi;"><b>Using run&lpar;&rpar; Method<&sol;b><&sol;span><&sol;h4>&NewLine;<p class&equals;"p2">We can use the <span style&equals;"color&colon; &num;008000&semi;"><strong>run&lpar;&rpar; <&sol;strong><&sol;span>method to execute some operations on a non-nullable reference&period; <b>This method operates using <span style&equals;"color&colon; &num;0000ff&semi;">this<&sol;span> reference and returns the value of the lambda result&colon;<&sol;b><&sol;p>&NewLine;<p><strong><span style&equals;"color&colon; &num;0000ff&semi;">Example&colon;<&sol;span><&sol;strong><&sol;p>&NewLine;<pre>fun main&lpar;args&colon; Array&lt&semi;String&gt&semi;&rpar; &lbrace;&NewLine;&NewLine; val cities&colon; List&lt&semi;String&quest;&gt&semi; &equals; listOf&lpar;"Kolkata"&comma; null&comma; "Mumbai"&comma; "Delhi"&comma; null&comma; "Banglore"&rpar;&NewLine; var newlist&colon; List&lt&semi;String&quest;&gt&semi; &equals; emptyList&lpar;&rpar;&NewLine; for &lpar;city in cities&rpar; &lbrace;&NewLine; city&quest;&period;run &lbrace;&NewLine; newlist &equals; newlist&period;plus&lpar;this&rpar;&NewLine; this&NewLine; &rcub;&quest;&period;also &lbrace;it-&gt&semi; println&lpar;"&dollar;it"&rpar; &rcub;&NewLine; &rcub;&NewLine; println&lpar;newlist&rpar;<&sol;pre>&NewLine;<p><strong><span style&equals;"color&colon; &num;0000ff&semi;">Output&colon;<&sol;span><&sol;strong><&sol;p>&NewLine;<pre>Kolkata&NewLine;Mumbai&NewLine;Delhi&NewLine;Banglore&NewLine;&lbrack;Kolkata&comma; Mumbai&comma; Delhi&comma; Banglore&rsqb;<&sol;pre>&NewLine;<h4><&sol;h4>&NewLine;<h4 class&equals;"p1"><span style&equals;"color&colon; &num;000080&semi;"><b>Elvis Operator &lpar;&quest;&colon;&rpar;<&sol;b><&sol;span><&sol;h4>&NewLine;<p class&equals;"p1"><b>We can use the Elvis operator&lpar;&quest;&colon;&rpar; to return a default value only if the original variable has a null value<&sol;b>&period;<&sol;p>&NewLine;<p class&equals;"p1">If the left-side expression of the Elvis operator has a non-nullable value&comma; then it is returned&period; Otherwise&comma; the right-side expression is returned&period;<&sol;p>&NewLine;<p>The following expression&colon;<&sol;p>&NewLine;<pre>name&quest;&period;length &quest;&colon; -1<&sol;pre>&NewLine;<p>is equivalent to&colon;<&sol;p>&NewLine;<pre>if &lpar;name &excl;&equals; null&rpar;&NewLine; name&period;length&NewLine; else&NewLine; -1<&sol;pre>&NewLine;<p class&equals;"p2"><strong style&equals;"font-size&colon; 16px&semi; font-family&colon; -apple-system&comma; BlinkMacSystemFont&comma; 'Segoe UI'&comma; Roboto&comma; Oxygen-Sans&comma; Ubuntu&comma; Cantarell&comma; 'Helvetica Neue'&comma; sans-serif&semi;"><span style&equals;"color&colon; &num;0000ff&semi;">Example&colon;<&sol;span><&sol;strong><&sol;p>&NewLine;<pre>fun main&lpar;&rpar; &lbrace;&NewLine; var name&colon; String&quest; &equals; "Arun"&NewLine; println&lpar;"Name length&colon; &dollar;&lbrace;name&quest;&period;length &quest;&colon; -1&rcub;"&rpar;&NewLine;&NewLine; name &equals; null&NewLine; println&lpar;"Name length&colon; &dollar;&lbrace;name&quest;&period;length &quest;&colon; -1&rcub;"&rpar;&NewLine;&rcub;<&sol;pre>&NewLine;<p><strong><span style&equals;"color&colon; &num;0000ff&semi;">Output&colon;<&sol;span><&sol;strong><&sol;p>&NewLine;<pre>Name length&colon; 4&NewLine;Name length&colon; -1<&sol;pre>&NewLine;<p><strong>We can also use <span style&equals;"color&colon; &num;0000ff&semi;">throw<&sol;span> and <span style&equals;"color&colon; &num;0000ff&semi;">return<&sol;span> expression in the right-side expression of the Elvis operator&period;<&sol;strong> So instead of default values&comma; we can throw specific exceptions in the right-side expressions of the <em class&equals;"kd"><strong><span style&equals;"color&colon; &num;008000&semi;">Elvis<&sol;span><&sol;strong> operator&colon;<&sol;em><&sol;p>&NewLine;<pre>var name&colon; String&quest; &equals; null&NewLine;val nameLength &equals; name&quest;&period;length &quest;&colon; throw IllegalArgumentException&lpar;"invalid length"&rpar;<&sol;pre>&NewLine;<h4 id&equals;"b6d2" class&equals;"kh ih dt ce ii kt ku eu im kv kw ex iq ey kx fa iu fb ky fd iy fe kz fg jc la eq"><strong><span style&equals;"color&colon; &num;000080&semi;">Not Null Assertion Operator &lpar; &excl;&excl; &rpar;<&sol;span><&sol;strong><&sol;h4>&NewLine;<p class&equals;"p2"><strong class&equals;"jg ks">We can use the not-null assertion operator&lpar;&excl;&excl;&rpar; to explicitly throw a NullPointerException<&sol;strong>&period;<&sol;p>&NewLine;<p class&equals;"p2">This operator converts any reference to its non-nullable type and throws an exception if the reference has a null value&period;<&sol;p>&NewLine;<p><strong><span style&equals;"color&colon; &num;0000ff&semi;">Example&colon;<&sol;span><&sol;strong><&sol;p>&NewLine;<pre>fun main&lpar;&rpar; &lbrace;&NewLine; var name&colon; String&quest; &equals; "Arun"&NewLine; println&lpar;"Name length&colon; &dollar;&lbrace;name&excl;&excl;&period;length&rcub;"&rpar; <strong><span style&equals;"color&colon; &num;008000&semi;">&sol;&sol; prints 4<&sol;span><&sol;strong>&NewLine;&NewLine; name &equals; null&NewLine; println&lpar;"Name length&colon; &dollar;&lbrace;name&excl;&excl;&period;length&rcub;"&rpar; <strong><span style&equals;"color&colon; &num;008000&semi;">&sol;&sol; Throws NullPointerException<&sol;span><&sol;strong>&NewLine;&rcub;<&sol;pre>&NewLine;<p><strong><span style&equals;"color&colon; &num;0000ff&semi;">Output&colon;<&sol;span><&sol;strong><&sol;p>&NewLine;<pre>Name length&colon; 4&NewLine;Exception in thread "main" kotlin&period;KotlinNullPointerException&NewLine;at ExampleKt&period;main&lpar;Example&period;kt&colon;44&rpar;&NewLine;at ExampleKt&period;main&lpar;Example&period;kt&rpar;<&sol;pre>&NewLine;&NewLine;

Exit mobile version