This is the part 5 of series Java to Kotlin - Learning Simplified. I hope you learn something new from every part. This part about a very important feature of Kotlin, Null safety.

If you have not read part 4 (Constructors and Inheritance), please do here.

Index of this part: Null Reference, Elvis ?:, Let, Safe Cast




Null Pointer and Safety


If you are a Java developer, you know the pain Null Reference brings. It has been famously called Billion Dollar Mistake. The reality is you can not get rid of the null objects as they are use case dependent. For example, if you are querying a database with some id and there is no record, the result object is null. Yes, there are alternatives like using Optional and checking isPresent OR get to play safe.

Kotlin takes a strong measure in this context. It says while architecting your project, you the developer knows an object can be null OR not. If there is no way you accept null then tell the compiler and let it help you. In java, even though you are sure as a developer that the object won’t be null, compiler can never be sure as there is no way to explicitly declare. Any Object is nullable in Java but in Kotlin by default all the objects are Non-Nullable

🀯 <- me again! This all sounds cool but I could not understand the meaning of non-null and how does it help. But as usual, I figured later this saves a lot of headache. Let me show you how:

πŸ’‘ First let me ask you a question. What happens if you are sure that an object will never be null? The simplest answer is you get rid of those ugly null checks. Remember concise? Why to check something if the smart compiler can do that for you. The whole purpose of high level language is to free the developer from nitty-gritty of the machine. Let’s see a snippet:

	// Java

	public String convertToLower(String input){
		return input.toLowerCase();
	}

In Java, every code block similar to the above one is null-prone Either you trust the caller OR you add a null-check everywhere. The former does not work in practice and the latter does not scale.

Kotlin introduced a new concept, Explicity Null Type. Every Class Type is either Non-Null (default) OR Nullable. Let’s see a snippet:

	// Kotlin

	fun convertToLower(input:String){
		return input.toLowerCase()
	}

πŸ”₯ What if I say you the above code is not-null-prone, Even if you call the function and try to pass null, the smart compiler will not allow you. Yes, that is possible and happens by default. There is no such notion in Java.

	// Kotlin
	convertToLower(null) ❌ wont compile, null not allowed

πŸ’‘ Unfortunately, it is out of scope to explain why NULL is bad and why is it better to be sure No null can sneak into your code.

But sometimes, we are ready to accept null. How to define a null type?

The syntax to define a null type is very simple and intuitive. It is the class type followed by question mark ?, So if your field/parameter can be a nullable String you need to say String? It means String and ? (nullable)

	// Kotlin
	fun convertToLower(input:String?){}

The code above accepts a String OR a null. You can pass a null and the compiler will not complain any more. Is that it? Is it all about Null safety in Kotlin? The answer is NO. It is half the story. Kotlin compiler is determined to save you from those null-pointer exceptions. It tries its best.

Accessing Nullable variable in Kotlin

In Java, there is no special treatment given to Nullables. But in Kotlin, there is one. You can not access a nullable variable like a normal one. It means you can not write this:

	fun convertToLower(input:String?){
		return input.toLowerCase() ❌ wont compile, null are not accessible like normal
	}

Here the compiler cries: The input is nullable and you are not doing anything to avoid the null pointer. There are a few ways in Kotlin to satisfy compiler and avoid null-pointers.

Explicit Null check

	fun convertToLower(input:String?){
		// βœ… explicit null check and smart compiler knows the rest
		return if(input == null) "" else input.toLowerCase() 
	}

The code above has an explicit null check, the smart compiler knows there can not be any null pointer and thus the code is allowed. But this is not Kotlin Style It is verbose like Java. Remember concise?

Access nullables safely and unsafely

The safe way ?.

Instead of the dot , we need question mark followed by dot and the Kotlin compiler will execute the statement only if the variable is non-null. If the statement is executed where return is expected like assignment OR function return, Compiler will return null from the statement. Here is a snippet of code:

	fun convertToLower(input:String?){
		// βœ… we used ?. syntax
		// value of length is either null (if input is null)
		// OR the length of input

		val length = input?.length 
	}

Similarly, if it is used in the context of a return statement, null will be returned if input is null.

	fun convertToLower(input:String?) : String? {
		// null will be returned if input is null
		return input?.toLowerCase()
	}

πŸ’‘ Check the return type in above code. it is String? to explicitly tell to compiler it can be null

The real power of ?. is you can club as many as you want. Suppose you have a Person class with Address member. You can do following:

person?.address?.city?.locality?.zipcode

Imagine how many if elses it will have in Java world!

The unsafe way !!.

If you are sure your object is non-null OR you are willing to take risk of null-pointer, then the syntax is !!.

	fun convertToLower(input:String?){
		// βœ… we used !!. syntax
		// value of length is the length of input
		// OR null pointer will be thrown in case it is null

		val length = input!!.length 
	}	

Similarly, if it is used in the context fo a return statement, null pointer will be thrown if input is null.

	fun convertToLower(input:String?) : String {
		// null pointer will be thrown if input is null
		return input!!.toLowerCase()
	}

πŸ’‘ Check the return type in above code. it is not String? but it is String as null will never be returned

In a nutshell, wherever you allow Nullable value, you need to use ? with the Type to tell compiler it is nullable. You can access the nullable in safe way null check / ?. OR you can opt for unsafe way !!. The unsafe way can throw null pointer.




Elvis Operator ?:


This is the right time to introduce you a new operator, Elvis ?: Your brain is already struggling with those ?. !!. syntax and I believe you can take more.

πŸ’‘?: is a helper operator to ?. the safe way to access nullables

You can club ?: when you do not want to return the null from ?. Here is a snippet:

	fun convertToLower(input:String?) : String {
		// it will never return null because of ?:
		return input?.toLowerCase() ?: "defaultvalue"
	}

In the above snippet, if the input is null then ?. will conclude null and ?: will execute and return the defaultvalue

πŸ”₯ Check the return type of the function, We do not need String? anymore

πŸ’‘ In reality, the alvis ?: can be used with null on the left side

	// this is a valid expression:

	val name = null ?: "Default Name"

πŸ’‘ The name will have Default value always




Let ?.let


As we saw the use of ?., we need ?. to safe use nullable variables. What happens if the variable you want to use is being used in multiple expressions after null check? Let’s see a snippet:

	// Kotlin

	fun doSomething(input:String?) {
			val length = input?.length
			val lower = input?.toLowerCase()
			val upper  = input?.toUpperCase()
			// and so on..
	}

Every expression containt input?. for the safe access. What if we want to execute the code when input is not null, we can write:

	// Kotlin

	fun doSomething(input:String?) {
			if(input != null) {
				val length = input?.length
				val lower = input?.toLowerCase()
				val upper  = input?.toUpperCase()
				// and so on..
		}
	}

Now the code will execute if the input is not null but an interesting part to note is we have to use ?. OR !!. which does not seem very good. Here comes the let to rescue

	// Kotlin

	fun doSomething(input:String?) {
			input?.let {
				val length = it.length
				val lower = it.toLowerCase()
				val upper  = it.toUpperCase()
				// and so on..
			}
		}
	}

The snippet above is same as the snippet before with if null check. The code will execute only if input is not-null. In reality Let is a function in Kotlin which accepts a block (more on this later)

πŸ’‘ We do not need nullables only to use let. We can use non-nullable as well

	// Kotlin

	fun doSomething(input:String) {
		input.let{
			val length = it.length
		}
	}

πŸ”₯ We have to use it inside the block to access the object which called let




Safe Cast as?


This is another fantastic use of ?, Do you remember we learned cast in Part 3. We have explicit cast and smart cast.

In Java, if the type of the object does not match the target, the ClassCastException will be thrown and same is the case with Kotlin. The slight difference is Kotlin offers a new syntax to play safe and be concise, here is a snippet:

	val myStr: String = input as? String

πŸ’‘ The above code tries to cast the input variable in String type, if it fails it will assign null to myStr. Java has no such offering.


Summary


I believe there are enough ? in this part. Although there are a few more syntax in Kotlin which include ?. In this part we saw how Kotlin compiler can help you and save null-pointer surprises. You can declare a variable OR return type nullable with ? at the end of the Type.

If something is nullable, Kotlin compiler will not allow you to access it normallly. There are special syntax ?. OR !!.. The former is a safe way and it returns β€˜null’ if the object is null and the latter is unsafe and it can throw null pointer exception. You can club multiple ?. and save an if-else ladder.

There is another syntax called alvis ?: which can be used with nullable left operand. If the left side is null, the right hand side value is assigned/returned. Finally we have safe cast as? which does not throw any exception and sets null if there is type mismatch.

We saw how we can utilise ?.let which is equivalent to having a not null check and a scoped function where we do not need ?. inside to access the object. We use it inside the block.

πŸ”₯ Hope you learned something, Null references and ? is a nice concept Kotlin introduced. Here is part 6

Subscribe to newsletter and keep learning good stuff

Email

πŸ‘‰ If you like article, click on β™₯️ recommend and share on social πŸ‘₯ media.
πŸ‘‰ Feel free to comment πŸ’¬
πŸ‘‰ Follow me πŸ‘€ for the more interesting articles. Twitter Medium
πŸ‘‰ Subscribe to newsletter and keep learning