Recently Kotlin programming is really endorsed by Google and most of the developers. We are not an exception. We moved to Kotlin for Android development and it was worth it. Here are 8 reasons why we did it.
1. Boilerplate code
Kotlin introduced Data Classes and many other features that reduce boilerplate code. For example copy() function that copies an object with the possibility to easily modify its state. This function saves a lot of space and you can use it on immutable values.
Here are a simple Data Class ‘Developer’
and ‘developerJohn’
that want to copy- changing only Developer’s name.
data class Developer(val firstName: String?, val lastName: String?, val age: Int?)
val developerJohn = Developer("John", "Kotlin", 10)
val twinDeveloperMark = developerJohn.copy("Mark")
I copied the first developer and created a twin brother with a different name but the same last name and age. As you can see, you can simply change one value even in an immutable object. It would be a chore to duplicate a bigger object manually only to change one value.
Java is getting better with each version but still forces a lot of boilerplate code. It offers ‘clone’
function but usually, it doesn’t work properly and developers advise to avoid it. So in Java, it would look like below.
class Developer {
private String firstName;
private String lastName;
private int age;
Developer(String firstName, String lastName, int age) {
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
Developer developerJohn = new Developer("John", "Kotlin", 10);
Developer twinDeveloperMark = new Developer("Mark", "Kotlin", 10);
‘Developer’
is fortunately a small model. Copying much bigger models manually is really annoying and space-wasting.
2. Null safety
Kotlin gives a smaller probability of app crashes because it’s easy to deal with NullPointerException. That’s where many operators come in handy. For example:
data class Developer(val firstName: String?)
fun handleDeveloper(developer: Developer?) {
developer?.firstName // get firstName if developer is not null
developer!!.firstName // get firstName even if developer is null -> may lead to crashes
developer?.let { // let me operate on developer in a block of code if developer is not null
it.firstName
}
}
Java 8 introduced Optional but it’s still harder to deal with NullPointerExceptions. Also, in Android development Java Optional is fully available only for Android 7.0+.
3. Flexibility
Android development with Kotlin is very flexible thanks to Extension Functions. If a class doesn’t have a useful function that would make your code fluid and readable- you can create this function yourself. For example, if you want to create a function that returns initials of the full name ->
fun Developer.getInitials(): String {
val firstNameInitial = firstName?.firstOrNull()?.toUpperCase()
val lastNameInitial = lastName?.firstOrNull()?.toUpperCase()
if(firstNameInitial == null || lastNameInitial == null) {
return "N/A"
}
return "$firstNameInitial$lastNameInitial"
}
By the way ‘firstOrNull()’
is an extension function too.
Java doesn’t provide Extension Functions, you are limited by methods that exist in a class or you have to override it. You can use regular static methods but it’s a less readable solution. If you want to do the same in Java, look below:
static String getInitials(Developer developer) {
Character firstNameInitial = null;
if (developer.getFirstName() != null) {
firstNameInitial = developer.getFirstName().toUpperCase().charAt(0);
}
Character lastNameInitial = null;
if (developer.getLastName() != null) {
lastNameInitial = developer.getLastName().toUpperCase().charAt(0);
}
if(firstNameInitial == null || lastNameInitial == null) {
return "N/A";
}
return firstNameInitial.toString() + lastNameInitial.toString();
}
4. Accessing views
Kotlin provides AndroidX synthetic imports. That’s why, in Activities, you can directly access Views using their ids assigned in XML. You don’t have to create new variables for them. That’s how it works:
developer_name.text = “John”
On the other hand, Java requires the use of findViewById which generates a lot of boilerplate.
developerName = (TextView) findViewById(R.id.developer_name);
developerName.setText(“John”)
Of course, you can use 3rd party libraries like Butterknife but it’s still a mess.
@BindView(R.id.developer_name) TextView developerName;
developerName.setText(“John”)
5. Defining types
In Kotlin you don’t have to define types because it’s optional. Usually, it’s redundant. The ‘val’
and ‘var’
operators take a while to get used to but are really rewarding.
val name = "John"
var age = 10
Java requires defining types and it makes your code less readable.
final String name = “John”
Int age = 10
6. Scope Functions
Kotlin provides scope functions, like ’run’
, 'with'
, 'let'
,‘also’
and 'apply'
, which execute a block of code within the context of an object.
Let’s say you want to do multiple operations on the same object. You don’t have to access it, again and again, every time. Declare that you want to work in a given scope using the Scope Functions and your life will be easier.
‘run’
,‘with’
and ‘let’
return the lambda result whereas ‘also’
and ‘apply’
return the context object.
popupMenu.run {
menuItemVisibility(R.id.action_close, canViewActionClose)
menuItemVisibility(R.id.action_open, canViewActionOpen)
menuItemVisibility(R.id.action_done, canViewActionDone)
menuItemVisibility(R.id.action_reject, canViewActionReject)
}
My favorite Scope Function is ‘let’
because it works perfectly with null safety.
menu.findItem(R.id.action_download)?.let { action ->
if (isActionDownloadAvailable) action.show() else action.hide()
}
If there is no action_download menu item, the block of code won’t execute. ‘Action’ inside the block of code is not non-nullable.
When it comes to Java- it doesn’t provide scope functions. You have to show context (popupMenu)
every time.
popupMenu.setMenuItemVisibility(R.id.action_close, canViewActionClose)
popupMenu.setMenuItemVisibility(R.id.action_open, canViewActionOpen)
popupMenu.setMenuItemVisibility(R.id.action_done, canViewActionDone)
popupMenu.setMenuItemVisibility(R.id.action_reject, canViewActionReject)
7. Switch statements
Kotlin offers 'when'
statements- 'switches on steroids'
. Also, Kotlin introduced sealed classes that are very useful for when statements. They can autofill all possible cases automatically (alt+enter driven development magic) and skip 'else'
a statement.
That’s how the Sealed Class implementation looks like:
sealed class FileResourceDownloadResult
data class DownloadResultSuccess(
val file: File,
val statusCode: StatusCode
) : FileResourceDownloadResult()
data class DownloadResultError(
val statusCode: StatusCode,
val throwable: Throwable
) : FileResourceDownloadResult()
For now, it may seem that there is nothing special. But here comes my favorite feature since 800 BC ->
return when (result) {
is DownloadResultSuccess -> Result.success()
is DownloadResultError -> Result.failure()
}
Notice that there is no else or default branch. You can return a non-nullable result and you don’t have to handle a redundant ‘else’
case. I hate this additional case because usually, it generates a lot of mess. Look at what you get when you want to do the same without the Sealed Class:
return when (result) {
is DownloadResultSuccess -> Result.success()
is DownloadResultError -> Result.failure()
else -> {
// error- you have to provide the else statement
}
}
Let’s get back to Java. It provides 'switch'
statements but they always require a default value too. Even if you handle all possible cases exclusively. That’s because Java doesn’t support sealed classes.
8. Official Android language
For a long time, Java was a standard language for Android development. It has changed two years ago when JetBrains introduced Kotlin. It quickly took over the Android development world.
By then, for a long time, Kotlin was preferred and promoted by many experienced developers but nobody considered this language as the first-class citizen. But recently Google officially announced that Kotlin is now a preferred language for Android development. Of course, Android still supports Java. But in the “Fragmented”, the biggest Android Dev podcast, Google engineers endorsed moving to Kotlin and explained that new code guidelines will be mostly tailored for this language. Fortunately, now it’s really easy to migrate to Kotlin.
Why we moved to Kotlin for Android development: summary
There are new and better features provided with each Java version. The problem is they are not popular in Android development. Some of them require Java 1.8 that is fully available only for Android 7.0+. The rest of them can’t be done in Java. But Kotlin has all great features organized and provided by default. So in 2019 Kotlin for Android development is a way to go.
Also, Kotlin has well-organized documentation that’s easy to read. You can find it here.
Check our other article connected with Android development.
Popular posts
From Hype to Hard Hats: Practical Use Cases for AI chatbots in Construction and Proptech.
Remember the multimedia craze in the early 2000s? It was everywhere, but did it truly revolutionize our lives? Probably not. Today, it feels like every piece of software is labeled "AI-powered." It's easy to dismiss AI chatbots in construction as just another tech fad.
Read moreFears surrounding external support. How to address concerns about outsourcing software development?
Whether you’ve had bad experiences in the past or no experience at all, there will always be fears underlying your decision to outsource software development.
Read moreWhat do you actually seek from external support? Identify what’s preventing you from completing a project on time and within budget
Let’s make it clear: if the capabilities are there, a project is best delivered internally. Sometimes, however, we are missing certain capabilities that are required to deliver said project in a realistic timeline. These may be related to skills (e.g. technical expertise, domain experience), budget (hiring locally is too expensive) or just capacity (not enough manpower). What are good reasons for outsourcing software development?
Read more