DEV Community

Cover image for #MakeTheChange: From Java to Kotlin
Tavon
Tavon

Posted on • Edited on

#MakeTheChange: From Java to Kotlin

So, you've decided to watch From Justin to Kelly?

Something tells me none of you even know this is a movie that exists.

Oh, wait. That's next week's post. Sorry. Wibbly wobbly. -Reads correct script- Ahem.

So, you've decided to switch from Java to Kotlin?

I'm so glad you've decided to join us. Cookies are in the back, and we have trips twice a year.

Switching from one programming language to another can feel intimidating and daunting. There's so many new things to learn, so many things that look similar but have a change that trip you up, and just so many surprises. As an Android developer, we had to weigh our options: did we want to switch to Kotlin just because it was new and shiny, or was there some benefit? Could it wait? Is there a way to try out just a little bit?

Automatic Java to Kotlin conversion

Android Studio came prepared with a solution once Kotlin was adopted as an officially supported language for Android apps. By clicking Code -> Convert Java File to Kotlin File, Android Studio will perform some basic transformation of Java to Kotlin for you. I personally think that's the best place to start if you're trying out Kotlin for the first time. Take a small class you know and understand well and convert it, looking over the changes and similarities. Be warned, Android Studio doesn't always do it the best way, but it's more than enough to get started with.

public class MainActivity extends Activity {

    @Override  
    protected void onCreate(@Nullable Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.id.activity_main);  
    }

}
Enter fullscreen mode Exit fullscreen mode
class MainActivity: Activity() {

    override fun onCreate(savedInstanceState: Bundle?) {  
        super.onCreate(savedInstanceState)  
        setContentView(R.layout.activity_main)  
    }

}
Enter fullscreen mode Exit fullscreen mode

From this quick example of a basic Activity, you can see that... not much is different. In Kotlin, everything is public by default, so we can leave that word out. extends (and implements) is transformed into a simple :. The @Override annotation is shifted to just become override and in line with the function name.

For me, the biggest change is that parameters and their types have shifted positions. Bundle savedInstanceState is now savedInstanceState: Bundle? (the question mark just means that it's Nullable). Also, lines don't end in semicolons, but you can add them if you want and it will still compile!

Data Classes

One of my favorite types of classes in Kotlin is Data classes. Here's a regular class in Java, with a constructor, getters, and setters.

public class YourObject {

    private String title;
    private int count;
    private @Nullable  String description;
    private boolean isActive = true;

    public YourObject(String title, int count, @Nullable String description, boolean isActive) {
        this.title = title;
        this.count = count;
        this.description = description;
        this.isActive = isActive;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

    @Nullable
    public String getDescription() {
        return description;
    }

    public void setDescription(@Nullable String description) {
        this.description = description;
    }

    public boolean isActive() {
        return isActive;
    }

    public void setActive(boolean active) {
        isActive = active;
    }
}
Enter fullscreen mode Exit fullscreen mode

This, my friend, is why I love Data classes:

data class YourObject(var title: String, var count: Int, var description: String?, var isActive: Boolean = true)
Enter fullscreen mode Exit fullscreen mode

DO YOU SEE THIS?!

Kotlin doesn't really do getters and setters (but then they do but it's... nevermind); it prefers property access syntax (that's what Android Studio calls it; pretty much, it wants you to use the variables directly). Data classes are also why I've moved away from builders. I feel as if named parameters fulfill the same purpose. Here's an example:

val item = YourObject(  
    title = "A Year In Love",  
    count = 525600,  
    description = "How do you measure a year in the life?"  
)  
Enter fullscreen mode Exit fullscreen mode

Using our Data class from before, we can create an instance of that class using named parameters. Everything feels neat and orderly. You can do them in any order (if you use the naming syntax, otherwise you have to do them in order). Your parameters that have default values aren't required (in constructors and methods).

Also, bonus love for data classes: they come with a .copy() method.

val aCopy = item.copy(description = null, 
                        title = "A Copy With No Description")

Enter fullscreen mode Exit fullscreen mode

Interfaces and Abstract Classes

Interfaces

Interfaces and Abstract classes function relatively the same and even look very similar. There are some small benefits on the Kotlin side, though.

public interface TestInterface {  
    void someInterfaceMethod();  
    String howAboutAnother(String someParam);  
}
Enter fullscreen mode Exit fullscreen mode
interface TestInterface {
    fun someInterfaceMethod()
    fun howAboutAnother(someParam: String): String

    fun forFunsies() {
        //  Some default implementation
    }
}
Enter fullscreen mode Exit fullscreen mode

The Kotlin example behaves the same, however, you can do something special with them, blurring the line between Interface and Abstract class so please use it wisely! In Kotlin interfaces, you can have non-required, default implementations of functions.

Abstract Class

There's less difference between a Java Abstract class and a Kotlin one, though there is one thing to note. Before I get into that, here's an example of an Abstract class in Java, with a class extending it:

abstract class AbstractJavaClass {

    abstract void someMethod();

    final void anotherMethod() {
        //default implementation  
        //this method can NOT be overriden, 'cause it's final
    }

    void yetAnotherMethod() {
        //default implementation  
        //this method CAN be overriden
    }

}

class ImplementationJavaClass extends AbstractJavaClass {
    @Override
    void someMethod() {
        //you're forced to implement this method

        anotherMethod();
        yetAnotherMethod();
    }

    // You can NOT override "anotherMethod" 

    @Override
    void yetAnotherMethod() {
        super.yetAnotherMethod();
        // you have the option of overriding this one, though
    }


}
Enter fullscreen mode Exit fullscreen mode

Similarly, here is an Abstract class in Kotlin with an associated extending class:

abstract class AbstractClass {  

    abstract fun someMethod()  

    fun anotherMethod() {  
        //default implementation  
        //this method can NOT be overriden  
    }  

    open fun yetAnotherMethod() {  
        //default implementation  
        //this method CAN be overriden  
    }  

}  

class Testing(): AbstractClass() {  

    override fun someMethod() {  
        //you're forced to implement this method  

        anotherMethod()  
        yetAnotherMethod()  
    }  

    // You can NOT override "anotherMethod"  

    override fun yetAnotherMethod() {  
        super.yetAnotherMethod()  
        // you have the option of overriding this one, though  
    }  

}
Enter fullscreen mode Exit fullscreen mode

You'll notice in my Java example I explicitly labeled a method as final. I did this to show the similarity in Kotlin: in Kotlin, all functions are final by default. The same is true for Classes as well. To make them non-final, you need to add open before it. (An open class would start off as open class ClassName)

Interoperability: Use Java and Kotlin together!

If you want to get started with Kotlin, dive right in! You can use Kotlin inside your existing Java applications and files, and existing Java inside your Kotlin files.

At my current company, there's been a slow conversion of Java to Kotlin, and a good 80%-90% of our main Android application is now in Kotlin. And I dread having to dredge through the untamed Java territory. But I know that when I do get to the lawless West of Java-land, I can still use a lot of my Kotlin code. Even my extensions!

I name my extensions classes in Kotlin based on the class I'm extending. For instance, if I was adding an extension to the Throwable class, I would make a file called ThrowableExtensions.kt. And, while I can't use the extension exactly like I would in Kotlin, if I need it in Java it's available to me in an automatically-generated class called ThrowableExtensionsKt, and I can access my extension function statically, passing in the object I would be acting on.

... that sounds confusing. 😂 Here's an example:

# in a file called ThrowableExtensions

fun Throwable.log() {
    /// my extension code
}
Enter fullscreen mode Exit fullscreen mode
public void someErrorMethod(Throwable throwable) {
    ThrowableExtensionsKt.log(throwable)
}
Enter fullscreen mode Exit fullscreen mode

For the full code of my Throwable extension (and other useful ones!), visit my previous blog post on five super-useful Kotlin extensions I use every day.

... And one* more thing

* = Actually, there's way more than one more thing.

Kotlin has a lot of different tricks up its sleeves, like val vs var (and even vs lateinit var). There are lazy variables, too! Oh, and classes can have Companions! But this post has gone on long enough. If there's something about Kotlin you'd like me to go over, let me know in the comments below or on Twitter @gatlingxyz .

This post originally appeared on my blog, Gatling.XYZ. You can check
out the original post here and maybe you'll find something else you like, too.

Top comments (2)

Collapse
 
rehab101 profile image
Prajjwal Srivastav

Thanks for the informative post. I wanted to ask if it makes more sense for someone to start out learning Android using Java and switch to Kotlin at a later stage compared to learning Android using Kotlin from the get-go, assuming no knowledge about Java in either case.

Collapse
 
gatlingxyz profile image
Tavon

Ooh, that's a tough one. Java is my foundation; it's the first programming language I learned in school. Switching to Kotlin was easy (or, easier) because I already had a foundation. Most of it is the same in both languages, with minor tweaks (such as no commas in Kotlin).

Personally, I would say just dive in with Kotlin for Android. It's officially supported, and a lot of stuff is happening with Kotlin in the forefront now. Start with Kotlin. If you find a tutorial in Java, you can always copy and paste it into Android Studio and it will automatically convert it to Kotlin for you as best as it can.