targets the JVM and (recently) JavaScript It is developed by a team at JetBrains (the people who create IntelliJ, the base for Android Studio) The team is based in St.Petersburg, Russia where the name Kotlin comes from the island of Kotlin which is near St.Petersburg. Kotlin Island
- As a comparison : - Support-v4 adds nearly 7000 - Rxjava adds more than 3500 - Okhttp3 adds over 2500 Kotlin syntax is simple and easy to learn Being from IntelliJ getting your first project up and running is very easy. https://kotlinlang.org/docs/tutorials/kotlin-android.html
Java can be called from Kotlin in a natural way, and Kotlin code can be used from Java rather smoothly A study showed a languages ecosystem (libraries, frameworks) are more important than a language's features when developers evaluate a language http://sns.cs.princeton.edu/docs/asr-oopsla13.pdf import java.util.Calendar.* val calendar = Calendar.getInstance() calendar.time = SimpleDateFormat(DATE_FORMAT, Locale.ENGLISH).parse(dateString)
significant annoyance in Java, which is partially solved in Kotlin If you have an ordinary variable definition, the compiler does not allow it to be null val text1: String = “something” // this is ok! val text2: String = null // this will not compile
option data type with a question mark Calling methods on an option type variable require an optional call if text2 is null, the replace() call is ignored and no NullPointerException is thrown. val text2: String? = null // this will now compile text2?.replace(“ ”, “_”)
can sometimes be difficult to read and understand the meaning of. For example in Java we might write: In Kotlin we can use named arguments to improve readability This can be very useful when we are passing many booleans ie true/false Profile profile = new Profile("Eoin", "Modge", 31); val profile = Profile("Eoin", nickname = "Modge", age = 31)
in order define different variants of a method or constructor. Take a look at this, a common example in Java where we create a custom view: public class CustomCardView extends CardView { public CustomCardView(Context context) { this(context, null); } public CustomCardView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public CustomCardView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(attrs); } private void init(AttributeSet attrs) { // init here }
effect with much less code. The compiler will generate alternate constructors for us so we don`t need to worry about it class CustomCardView @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 ) : CardView(context, attrs, defStyleAttr) { init { // init here } }
we want equals(), hashcode() and toString() we have to add these methods to the class. This is a lot of boilerplate code for such a simple class. public class Book { private String title; private String author; public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } }
: With this class we have getters and setters, equals(), hashcode() and toString() all generated for us. We can now also easily copy data classes data class Book(var title: String, var author: String) val sequel = book.copy(title = "Hyperion")
existing classes without inheriting from them. Below we have a utility function that converts an int to dp To call it we might do something like public fun toDp(dp: Int): Float { val metrics = Resources.getSystem().displayMetrics val px = dp * (metrics.densityDpi.toFloat() / DisplayMetrics.DENSITY_DEFAULT) return px } val dp = ResourceUtil.toDp(16)
new members to a project will be unaware of these Util classes and could duplicate existing code. It would be nice if we could provide the functionality to the base class itself. We can then call this method from Int types public fun Int.toDp(): Float { val metrics = Resources.getSystem().displayMetrics val px = this * (metrics.densityDpi.toFloat() / DisplayMetrics.DENSITY_DEFAULT) return px } val dp = 16.toDp()
Usually you see it in things like loggers. In Java, there’s several ways to implement a singleton, and the best practice changed over time. In Kotlin, you just create an object at a package level as access as a singleton A more complex example object Singleton object Logger { val tag = "TAG" fun d(message: String) { Log.d(tag, message) } }
name, and then the value. In Kotlin, it’s a little backwards. You define the name, then the type, and then assign the value. In most cases, though, you don’t need to define the type. var string: String = "" var string = "" var char = ' ' var int = 1 var float = 0F var double = 0.0 var boolean = true var foo = MyFooType()
you can access it as that type without explicitly casting it. Here’s an example, Java : In Kotlin: We check to see if x is a string, and if it is we print the length. To do that we use the is keyword. It’s similar to instanceOf in Java, and since it passes the check, we can treat it like a string anywhere after the check. if (x is String) { print(x.length()) } if (x instanceof String) { print(((String) x).length()); }
this requires some work (retrolambda etc), lambdas in Kotlin are supported out of the box. So we can write something like this. A difference with Kotlin if a parameter is not used we don’t need to include it button.setOnClickListener { view -> Toast.makeText(...).show() } button.setOnClickListener { Toast.makeText(...).show() } // no view