Introduction
At Google IO 2017, the Search Engine giant announced Kotlin as the official language for Android development. Since then, Java vs Kotlin has become a raging debate.
As of Android Studio 3.0 (released in October 2017), Kotlin is fully supported by Google for use with their Android operating system, and is directly included in the IDE’s installation package as an alternative to the standard Java compiler.
Even if you can write Android applications in numerous programming languages, including C#, C/C++, Lua, Scala, JavaScript, and Clojure; Java is the first language that springs to mind for Android app. It is still favorite of the Android app development world. With 67 percent, Java is the 2018’s second most popular language on GitHub, after JavaScript (97 percent). Kotlin, a relatively new language launched by JetBrains, is challenging the Java’s leadership in the Android development community. Let’s learn more about Java and Kotlin before comparing the two.
Java
Developed by Sun Microsystems (now acquired by Oracle Corporation) in 1995, Java, an object oriented programming language, is one of the most popular programming languages in use, with a reported 9 million developers.
We all know Android itself is written in Java and hence is favorite of many Android developers across the world. Some of the pros of Java Includes:
- Flexible: You can run it a virtual machine or in a browser window. It’s really helpful when you update software or reuse code;
- Fast Development Speed: Java offers faster build process (even faster than Kotlin);
- Compact Apps: Java apps are comparatively lighter than the Kotlin Apps;
- Java is a recommended choice for cross-platform mobile applications;
- Google has chosen JVM (Java Virtual Machine) for Android and hence Java has a large open-source ecosystem
Kotlin
Designed by JetBrains, Kotlin was launched with an idea to add some modern features in Java. It is an open source, statically typed language based on JVM (Java Virtual Machine) but it can also be compiled to Native or JavaScript for building code that can run on iOS.
Kotlin is fully compatible with existing Java stacks and with just one Plugin, you can easily switch from Java to Kotlin. Some of the pros of Kotlin Includes:
The first officially stable release of Kotlin v1.0 was on February 15, 2016.
- To help developers build clean APIs, Kotlin includes smart extensions
- Kotlin has null in its type system; solving nullability problems of Java
- Kotlin is more concise, requires less code and hence there are less opportunities of errors
- Kotlin is interoperable with Java
- Switching from Java to Kotlin is pretty easy
Head to Head Comparison
Both Kotlin and Java are popular in the Android development community, however, both have their pros and cons. Some Java issues addressed in Kotlin
- Null references are controlled by the type system
- Kotlin does not have checked exceptions
- Arrays in Kotlin are invariant
- No raw types
- Use-site variance without wildcards
- Kotlin has proper function types, as opposed to Java’s SAM-conversions
- Excellent IDE Support: JetBrains’ own platform, IntelliJ IDEA, serves as the base for Android Studio – offering extensive IDE support to the programming language. The integration with the IntelliJ IDEA framework offers a significant range of productivity tools. Moreover, one can configure Kotlin plugin within minutes in the Android Studio. The improved support of IDE makes process of coding in Kotlin, navigation, debugging and unit testing easier for developers.
- Enhanced Versatility: Kotlin was designed to address some of the issues in Java and experts believe that it did well. The built-in null checking feature of the programming language helps avoid frequent errors. Kotlin’s compiler also has a feature that automatically fixes mistakes in the code simultaneously while being written in the console – giving a clean and versatile platform to work with.
Here are some of the major differences between them
Difference #1: Null Safe
In Java, NullPointerException is real pain for the developers. It allows developers to assign null to any variable, however, while fetching an object reference that has a null value, it raises a null pointer exception which developer needs to handle.
Kotlin has tried to fix this issue of Java by making all types of variables non-null able by default. That means, developers can’t assign null values to any variable/object. When developers assign or return null values, Kotlin code will fail during compile-time. However, we can declare a null value, as follows:
value num: Int? = null
Difference #2: Extension Functions
Extension functions are not available in Java. To extend the functionality of existing class, developers need to create a new class and inherit the parent class.
In Kotlin, developers can easily extend an existing class with new functionality. To extend, developers can create extend functions by prefixing the name of a class to name of the specific new function.
Difference #3: No checked exceptions
Java has checked exceptions support, which provides developers the ability to declare and catch the exception. That’s why Java has robust code with good error handling.
However, Kotlin doesn’t have checked exceptions, hence developers don’t need to declare or catch the exceptions. It has its own advantages and disadvantages.
Difference #4: Functional Programming
Until Java 8, Java didn’t have functional programming support. However, Java supports the only subset of Java 8 features when developing mobile applications.
Being a mix of procedural and functional programming language, Kotlin consists of numerous methods for developers including operator overloading, lambda, lazy evaluation, higher-order functions, etc
Difference #5: Data classes
In Java, to have a class that hold data but nothing else, developers need to define constructors, variables to store data, getter and setter methods, toString(), hashcode(), and equals() functions
In Kotlin, to have a class that hold data, developers can simply declare the class with keyword “data†in the class definition. Afterward, the compiler will do the rest; creating constructors, getter and setter methods for numerous fields.
Difference #6: Type inference
While declaring, developers need to specify the type of each variable explicitly in Java.
In Kotlin, developers don’t need to specify the type of each variable explicitly based on assignment. If developers want to, they can specify explicitly.
Difference #7: Smart casts
In Java, We need to check the type of variables and cast according to our operation.
In Kotlin, smart casts will handle these casting checks with keyword “is-checks†which will check for immutable values and performs implicit casting.
Difference #8: Overriding
Overidding the methods of a supper class in java with @Override keyword will now be overridden with the keyword override in kotlin. The below code show the overriden of onCreate which is the first method to be invoke in a running activity while creating such activity in android
//JAVA
@Override
protected void onCreate(Bundle savedInstanceState) {
}
//KOTLIN
override fun onCreate(savedInstanceState: Bundle?) {
}
Difference #9: Nullable variable
We declare a nullable variable field in java like this
private Button sayHello;
and further assign value to it like in constructor or method like this
sayHello = (Button)findViewById(R.id.helloButton);
You will want to do this in Kotlin as follow
private var sayHello: Button? = null
and further assign value to it like in constructor or method like this
sayHello = findViewById(R.id.helloButton) as Button?
Difference #10: Inheritance and It's Keyword
“extends” keyword is a five character word for implimenting inhentance in java but this has been replced with “:†keyword in kotlin
//the java way to implement inheritance using extends keyword
public class MainActivity extends AppCompatActivity {
}
//the Kotlin way to implement inheritance using : keyword
class MainActivity : AppCompatActivity() {
}
Difference #11: Public keyword in class declaration
In java, it’s a doctrin to have the class name that has the same name as file name to be a public class. It’s not neccessary in kotlin if you are inheriting a class. It assummes thesame visibility modifier for child class
// java way of declaring a public class
public class MainActivity extends AppCompatActivity {
}
the kotline equivalent without “public” – visibility modifier
// the kotlin way of class declaration
class MainActivity : AppCompatActivity() {
}
Difference #12: Inheritance
//the java way to implement inheritance using extends keyword
public class MainActivity extends AppCompatActivity {
}
//the Kotlin way to implement inheritance using: keyword
class MainActivity : AppCompatActivity() {
}
Difference #13: .apply operator
When we have to instantiate a Fragment, Android makes us do it through a static method in which we will build a Bundle where we write the arguments that we want to pass to the Fragment. This is because this Bundle is stored by the operating system in order to rebuild this Fragment in case it is destroyed.
In Java we would need to do something like this:
static MyFragment newInstance(String arg1, String arg2) {
MyFragment fragment = new MyFragment();
Bundle arguments = new Bundle();
arguments.putString(ARG_1_KEY, arg1);
arguments.putString(ARG_2_KEY, arg2);
fragment.setArguments(arguments);
return fragment;
}
While in Kotlin, using the .apply operator, we would do something like this:
companion object {
fun newInstance(arg1: String, arg2: String): MyFragment {
return MyFragment().apply {
arguments = Bundle().apply {
putString(ARG_1_KEY, arg1)
putString(ARG_2_KEY, arg2)
}}}}
While there is no difference in the number of lines between the two snippets, in Kotlin it is not necessary to keep references to the Fragment or the Bundle, and we can also narrow the scope of each part of the code, since we know that within each .apply we are writing code in which this will refer to the object on which we have made the .apply
Difference #14: Lambdas and functions as parameters
To link the events of the view with those of the service, instead of exposing the Observable directly so that the other party can do the subscription, we expose methods that receive functions as parameters; functions that will be executed when an event occurs either in the view or in the service, such as:
//JAVA
public interface View {
void requestData(Consumer func);
void onDataLoaded(Data newData);
}
public interface Service {
void getData(boolean isPaginating);
void onDataLoaded(Consumer func);
}
public class Presenter {
Presenter(final View view, final Service service) {
view.requestData(service::getData);
service.onDataLoaded(view::onDataLoaded);
}
}
//KOTLIN
interface View {
fun requestData(func: (isPaginating: Boolean) -> Unit)
fun onDataLoaded(newData: Data)
}
interface Service {
fun getData(isPaginating: Boolean)
fun onDataLoaded(func: (data: Data) -> Unit)
}
class Presenter(view: View, service: Service) {
init {
view.requestData {
service.getData(it)
}
service.onDataLoaded {
view.onDataLoaded(it)
}}}
The main difference between these implementations ( java vs kotlin ) is the fact that in Java we need to use the Consumer class to pass a function as a parameter (in this case a function that receives an input parameter of Boolean type and does not return anything). If we wanted this function that we passed as a parameter to return something, we would have to change Consumer to Function, and if we didn’t want to have an input parameter, we would have to use Supplier instead. But the thing does not end here, if instead of having one parameter, we would like to have two, we need to use BiFunction or BiConsumer. But if we would like to have three instead of two, Java does not provide us with a solution as we might expect (TriFunction or TriConsumer), or we build it by ourselves or we use Function <T, Function <U, R >> or Function , U>. Any of the solutions is definitely less readable and more complicated to define and implement than that provided by Kotlin, where this option is integrated into the language itself.
Difference #15: Annotation processing libraries with Kotlin
Kotlin supports all existing Java frameworks and libraries, including advanced frameworks that rely on annotation processing, although some Java libraries are already providing Kotlin extensions, such as RxKotlin.
If you do want to use a Java library that relies on annotation processing, then adding it to your Kotlin project is slightly different as you’ll need to specify the dependency using the kotlin-kapt plugin, and then use the Kotlin Annotation processing tool (kapt) instead of annotationProcessor. For example:
XML
//Apply the plugin//
apply plugin: 'kotlin-kapt'
//Add the respective dependencies using the kapt configuration//
dependencies {
kapt “com.google.dagger:dagger-compiler:$dagger-version”
…
…
…
}
Difference #16: implicit widening conversions
Kotlin doesn’t support implicit widening conversions for numbers, so smaller types aren’t implicitly converted to bigger types. In Kotlin, if you want to assign a value of type Byte to an Int variable, then you’ll need to perform an explicit conversion, whereas Java has support for implicit conversions.
Difference #17: Setting properties of an object
We can set property of an object in java using set method as defined by the Class of the object instigated. Looking at the sample codes below
hello.setVisibility(EditText.VISIBLE);
the setVisibility method is not needed to set property as you will want do this by changing visibilty property and assign corresponding value to it. i.e
hello!!.visibility = EditText.VISIBLE
Difference #18: Support for constructors
Unlike Java, a Kotlin class can have a primary constructor and one or more secondary constructors, which you create by including them in your class declaration:
class MainActivity constructor(firstName: String) {
}
Statement terminator: We have this new way of writing a complete statement without semi colon to show the end of statement i.e.
import android.os.Bundle; // the usual way of indicating a statement
import android.os.Bundle // the Kotlin way without;
Difference #19: Coroutines Support
In Java, the corresponding thread gets blocked whenever we initiate a long-running network I/0 or CPU Intensive operations. We all know Android is a single-threaded by default. Java enables users create multiple threads in the background and run. However, managing them is a complex task.
Kotlin has Coroutines support. So even if developers create multiple threads to run these long-running intensive operations, the support will suspend execution without blocking threads.
In an example of documentation of Kotlin we can see this situation in which the instantiation of one million Threads and one million coroutines is compared:
val c = AtomicInteger()
for (i in 1..1_000_000)
thread(start = true) {
c.addAndGet(i)
}
println(c.get())
val c = AtomicInteger()
for (i in 1..1_000_000)
launch {
c.addAndGet(i)
}
println(c.get())
The code illustrates that it is definitely faster to use coroutines than threads in java.
Conclusion
While Kotlin offers many advantages and modern properties, it still has some shortcomings. While Kotlin requires approximately 20 percent less coding compared to Java, Java will remain essential for Android app development. However, you can experiment with Kotlin step by step to check if the new language is benefitial for your firm/project.
If you want to build an Android app with Kotlin, get in touch with our team. We will help you build the best Android or Cross Platform app for you and your business.
Source: codementor.io, kotlinlang.org