Java To Kotlin Part 3 — Variables And Syntactic Sugar

Michael Duivestein
Tech@Travelstart
Published in
4 min readNov 4, 2018

Part 2 demonstrated most of the different ways that classes and methods can be used in Kotlin. Part 3 will demonstrate most of the cool things that Kotlin can do with variables. This is where things start to get interesting and fun.

In Kotlin, member variables(class-level variables) are called “properties”, while local variables are called “locals”. As many parts of this blog post refer to things that can apply to both properties and locals, the word “variable” may be used as a substitute.

Visibility modifiers (public/private/default/internal)

Kotlin, like Java, has four visibility modifiers. There are the usual public, protected, and private modifiers, and they work the in mostly the same way as Java:

  • public objects are visible anywhere that accesses the class it’s declared in. The public is considered redundant as the default modifier for variables is public.
  • protected objects are only visible to the class they’re declared in and any child classes.
  • private objects are only visible inside the class they’re declared in. The only difference

The fourth modifier is internal. A object bearing this modifier is only visible to every class in the same module.

Constants

Constants in Kotlin work a bit differently to Java. For starters they’re accessible from anywhere in the package or module they’re declared in. This means it’s possible to create a file to contain every constant for the module. Should a less public constant be needed, one of the visibility modifiers would work. Remember: the protected modifier will not work for constants in this context, as it’s outside of a class.

Getters and Setters

In Kotlin, all properties have invisible getters and setters. A property is only accessible through it’s getters and setters. The default getter and setters are transparent, so we just access the variable name instead. Manually adding getters and setters is not needed unless a variable needs to be modified before being set/get. Kotlin has a handy getter/setter combo for this:

In this case, department can be null, but we don’t want to get or set it as null. Remember the part about Kotlin having built-in getters and setters? We don’t need to call getDepartment(), as that method is completely transparent. Instead we just access the variable as per normal:

This would be a good time to show some cleaned-up decompiled bytecode for the above code:

All nicely wrapped up for use in Java.

If you’d like a custom getter and setter, the Kotlin standard recommends creating a dummy property with no backing field:

The decompiled bytecode for this would be:

The Elvis Operator

There is the following expression in GettersAndSetters:

This can be refined by the Elvis operator (?:):

This is a convenient shorthand expression that will set a nullable variable if it is not null, else set it to whichever value is on the other side of the elvis expression (or throw an exception, if that’s useful).

Not-Null Assertion

As demonstrated in parts 1 & 2, variables are made nullable using the ? character. A null-check can be made to assign a nullable variable to a not-null variable. If the situation arises when a nullable variable must not be null, the !! (non-null) operator can be appended to the variable when being used. This will throw an exception if the variable is null:

The non-null operator actually converts the nullable type to a non-null type. non-Null asserting properties and variables should be done as early as possible. This should result in possible errors being detected earlier in code execution.

Lateinit

When a non-null var is declared, it must normally be assigned immediately. The lateinit modifier allows a var to be declared empty and assigned later:

A value must be set to alateinit var, or an UninitializedPropertyAccessException will be thrown when it’s accessed:

String Interpolation

String interpolation is one of my favourite Kotlin features. It allows the addition of variables into a String without resorting to concatenation:

On the surface it looks simple. The decompiled bytecode code simply used concatenation:

Methods calls can also be used surrounded by ${}:

The above will be compiled into simple concatenation, so don’t be concerned about this being expensive at execution time.

String interpolation also works with expressions:

It’s not just limited to arithmetic:

Interpolation can also be nested. This can be abused to create some pretty absurd and crazy logic that is guaranteed to attract the unbridled wrath of your coworkers:

JoinToString

joinToString is a handy method that outputs the contents of a collection to a String. The prefix, suffix, and separator can be defined. lastly, the maximum number of elements to add to the String can be specified:

String Equality

Kotlin has a much more mature outlook on String equality than Java. The .equals() method is no longer needed. That’s right. Strings can be checked for equality in the same way as anything else:

Smart Casting

I saved the best for last. Kotlin has an amazing smart casting system. It remembers what a variable has been cast to. This allows for some cleaner code than continually casting a variable:

This is the end of Part 3. Compared to Parts 1 and 2, Part 3 included some more juicy stuff to sink your teeth into. Part four should be even better.

Examples for Part 3 can be found here.

Part 4 of the series can be found here.

Originally published at www.k0ma.co.za on November 4, 2018.

--

--