Kotlin code

Initial Impressions of Kotlin

As almost every Android developer has heard of by now, Kotlin is being included as a first class language in Android Studio. Kotlin is a language created by JetBrains, the same company that is responsible for IntelliJ Idea, the core of Android Studio. Originally, a plugin was required to use Kotlin from within Android Studio.

Multiple Targets

I am greatly interested in the evolution of the Kotlin ecosystem since Kotlin can compile to multiple targets, currently compiling to Java and JavaScript with future plans to support iOS and desktop environments as targets — the largest example of this being Xamarin, based upon C#. Due to limitations imposed by Apple for development of Mac OS and iOS applications, a Mac is required to complete the build for those platforms. Xamarin's development environments only support Mac OS and Windows, with no Linux support. Kotlin, however, has support in IntelliJ Idea and now Android Studio. Both of these development environments support Windows, Mac OS, and Linux. As an open source enthusiast, Linux support helps tremendously as it is my primary OS.

Java Interoperability

Kotlin has full interoperability with Java. This thankfully means that you do not have to wait for a new project to begin writing Kotlin code. This also means that current projects do not need a full immediate rewrite in order to start reaping some of the benefits of using Kotlin. You can call Java objects and methods from within Kotlin code and Kotlin objects and methods from within Java code. While I applaud the interoperability, I am concerned that it may be even easier for careless developers to make more mistakes and leave code worse off than previously, even with all of the benefits that Kotlin brings.

Concise Code

The first of two language features that I'm looking forward to with Kotlin is that the code will likely be much more concise compared to Java, especially when you work with data classes in Kotlin. An example model class in Java could be similar to:

public class SampleModel {
 
    private String mName;
    private int mAge;
    private int mHeight;
    private int mWeight;
    private String mAddress;
    private String mPhone;
    private Date mBirthday;
    private String mCity;
    private String mState;
    private int mZipCode;
 
    public String getName() {
        return mName;
    }
 
    public void setName(String name) {
        mName = name;
    }
 
    public int getAge() {
        return mAge;
    }
 
    public void setAge(int age) {
        mAge = age;
    }
 
    public int getHeight() {
        return mHeight;
    }
 
    public void setHeight(int height) {
        mHeight = height;
    }
 
    public int getWeight() {
        return mWeight;
    }
 
    public void setWeight(int weight) {
        mWeight = weight;
    }
 
    public String getAddress() {
        return mAddress;
    }
 
    public void setAddress(String address) {
        mAddress = address;
    }
 
    public String getPhone() {
        return mPhone;
    }
 
    public void setPhone(String phone) {
        mPhone = phone;
    }
 
    public Date getBirthday() {
        return mBirthday;
    }
 
    public void setBirthday(Date birthday) {
        mBirthday = birthday;
    }
 
    public String getCity() {
        return mCity;
    }
 
    public void setCity(String city) {
        mCity = city;
    }
 
    public String getState() {
        return mState;
    }
 
    public void setState(String state) {
        mState = state;
    }
 
    public int getZipCode() {
        return mZipCode;
    }
 
    public void setZipCode(int zipCode) {
        mZipCode = zipCode;
    }
 
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
 
        SampleModel that = (SampleModel) o;
 
        if (mAge != that.mAge) return false;
        if (mHeight != that.mHeight) return false;
        if (mWeight != that.mWeight) return false;
        if (mZipCode != that.mZipCode) return false;
        if (mName != null ? !mName.equals(that.mName) : that.mName != null) return false;
        if (mAddress != null ? !mAddress.equals(that.mAddress) : that.mAddress != null)
            return false;
        if (mPhone != null ? !mPhone.equals(that.mPhone) : that.mPhone != null) return false;
        if (mBirthday != null ? !mBirthday.equals(that.mBirthday) : that.mBirthday != null) {
            return false;
        }
        if (mCity != null ? !mCity.equals(that.mCity) : that.mCity != null) return false;
        return mState != null ? mState.equals(that.mState) : that.mState == null;
 
    }
 
    @Override
    public int hashCode() {
        int result = mName != null ? mName.hashCode() : 0;
        result = 31 * result + mAge;
        result = 31 * result + mHeight;
        result = 31 * result + mWeight;
        result = 31 * result + (mAddress != null ? mAddress.hashCode() : 0);
        result = 31 * result + (mPhone != null ? mPhone.hashCode() : 0);
        result = 31 * result + (mBirthday != null ? mBirthday.hashCode() : 0);
        result = 31 * result + (mCity != null ? mCity.hashCode() : 0);
        result = 31 * result + (mState != null ? mState.hashCode() : 0);
        result = 31 * result + mZipCode;
        return result;
    }
 
    @Override
    public String toString() {
        return "SampleModel{" +
                "mName='" + mName + '\'' +
                ", mAge=" + mAge +
                ", mHeight=" + mHeight +
                ", mWeight=" + mWeight +
                ", mAddress='" + mAddress + '\'' +
                ", mPhone='" + mPhone + '\'' +
                ", mBirthday=" + mBirthday +
                ", mCity='" + mCity + '\'' +
                ", mState='" + mState + '\'' +
                ", mZipCode=" + mZipCode +
                '}';
    }
}

Using the tools to automatically convert this Java code to Kotlin will be a little more concise, giving you:

class SampleModel {
 
    var name: String? = null
    var age: Int = 0
    var height: Int = 0
    var weight: Int = 0
    var address: String? = null
    var phone: String? = null
    var birthday: Date? = null
    var city: String? = null
    var state: String? = null
    var zipCode: Int = 0
 
    override fun equals(o: Any?): Boolean {
        if (this === o) return true
        if (o == null || javaClass != o.javaClass) return false
 
        val that = o as SampleModel?
 
        if (age != that!!.age) return false
        if (height != that.height) return false
        if (weight != that.weight) return false
        if (zipCode != that.zipCode) return false
        if (if (name != null) name != that.name else that.name != null) return false
        if (if (address != null) address != that.address else that.address != null)
            return false
        if (if (phone != null) phone != that.phone else that.phone != null) return false
        if (if (birthday != null) birthday != that.birthday else that.birthday != null) {
            return false
        }
        if (if (city != null) city != that.city else that.city != null) return false
        return if (state != null) state == that.state else that.state == null
 
    }
 
    override fun hashCode(): Int {
        var result = if (name != null) name!!.hashCode() else 0
        result = 31 * result + age
        result = 31 * result + height
        result = 31 * result + weight
        result = 31 * result + if (address != null) address!!.hashCode() else 0
        result = 31 * result + if (phone != null) phone!!.hashCode() else 0
        result = 31 * result + if (birthday != null) birthday!!.hashCode() else 0
        result = 31 * result + if (city != null) city!!.hashCode() else 0
        result = 31 * result + if (state != null) state!!.hashCode() else 0
        result = 31 * result + zipCode
        return result
    }
 
    override fun toString(): String {
        return "SampleModel{" +
                "mName='" + name + '\'' +
                ", mAge=" + age +
                ", mHeight=" + height +
                ", mWeight=" + weight +
                ", mAddress='" + address + '\'' +
                ", mPhone='" + phone + '\'' +
                ", mBirthday=" + birthday +
                ", mCity='" + city + '\'' +
                ", mState='" + state + '\'' +
                ", mZipCode=" + zipCode +
                '}'
    }
}

Not much of a savings. However, if you were to write this by hand and use the data class feature, you would see drastic consolidation of code to get:

public data class SampleModelKotlin(private var mName: String, private var mAge: Int,
                                    private var mHeight: Int, private var mWeight: Int,
                                    private var mAddress: String, private var mPhone: String,
                                    private var mBirthday: Date, private var mCity: String,
                                    private var mState: String, private var mZipCode: Int)

We go from about 150 lines of code in pure Java, to 60 lines of code just by running the conversion tool in Android Studio, to just five lines, which would be one line if we weren't limiting max line length, with Kotlin's data class. This is one of the more drastic areas where Kotlin creates more concise code by removing a lot of boilerplate, however, there are others.

More Robust Code

The second of the language features that I'm looking forward to with Kotlin is that your code will be more robust and less prone to certain errors, especially NullPointerExceptions. This is because of how Kotlin handles the null case. Unless explicitly declared with the ? operator, objects in Kotlin cannot be null. Kotlin's type casting system also tries to reduce the amount of explicit casting you have to do; however, you still need to check to makes sure the object is capable of being cast to the type you desire.

Final Remarks

Kotlin is here with the full backing of Google. It would behoove Android developers to begin learning Kotlin, because even if Google has pledged to keep supporting Java, I could see scenarios where Java support is dropped in the future. Especially if Google ever gets tired of dealing with Oracle and the numerous legal battles that have ensued over the Java APIs. This, combined with the benefits over Java that Kotlin brings, make this a language that any Android developer would be wise to start picking up.

Add new comment

Restricted HTML

  • Allowed HTML tags: <a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • You can enable syntax highlighting of source code with the following tags: <code>, <blockcode>, <cpp>, <java>, <php>. The supported tag styles are: <foo>, [foo].
  • Web page addresses and email addresses turn into links automatically.
  • Lines and paragraphs break automatically.

About the Author

James Simshaw, Senior Software Engineer

James went to Oregon State University to get a degree in computer science, and came out with degrees in computer science and mathematics. Having traversed the technical realm and some non-technical stops, James has found that his passions relate to solving problems and puzzles while helping improve the lives of others. Now, with his love of open source software, James is currently creating Android apps to enhance the lives of others.

James loves great stories, from anime, manga, novels, television shows to video games, board games, and Dungeons and Dragons. In addition to these, James loves attending conventions throughout the year.

Ready for transformation?