Kotlin vs Java (del 1 ud af 2)

 
 Kotlin vs Java Android udvikling

Introduktion af Kotlin

Kotlin er et ‘static typed language’, der som ide udfoldede sig tilbage i 2010. Sproget er udviklet til at være ‘concise, safe, pragmatic and focused on interoperability with Java’.

Concise and Pragmatic

Sproget fokuserer på at programmere på et højere niveau, hvor boilerplate koden kan abstraheres væk. Abstraheringen af boilerplate kode medfører, at programmøren kan fokusere på det væsentlige i den givne metode eller applikation. Et godt eksempel heraf er deklareringen af en dataklasse.

Java

I Java kan en simpel Person klasse defineres ved overskrivning af toString, equals og hashcode samt getters og setters til klassens variabler.

Public class Person {
	private int age;
	private string name;
	public Person(int age, string name) {
		this.age = age;
		this.name = name;
	}

	public Integer getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public Integer getName() {
		return name;
	}

	public void setName(string name) {
		this.name = name;
	}

	@override
	toString, equals, hashcode…
}

Kotlin

Ved første blik på Person klassen, kan der tænkes, hvilke dele er boilerplate? Hvor meget kan skæres væk? Som svar defineres den tilsvarende klasse i Kotlin som 1 klasse med 2 properties:

data class Person( val name : String, val age: Int)

Her er det tydeligt illustreret, at der kan spares tid ved udeladelse af alt boilerplate koden, som er et krav for at Java compileren kan compile Person klassen.

Ved at sætte ‘data’ nøgleordet før ‘class’ fortæller Kotlin compileren at dette er en data klasse og compileren reagerer ved at autogenerere toString, equals, hashcode samt nogle ekstra hjælpefunktioner. 

Kotlins variabler kan enten være en immutable value ‘val’ eller en mutable variable ‘var’. I dette tilfælde i constructeren er begge klassens properties values og compileren generere en simpel getter til begge values, så de kan refereres i koden. Hvis de var defineret som ‘var’ ville compileren også have genereret en simpel setter til propertyen.

Ved at skære boilerplate koden fra, bliver koden mere præcis samt mere overskuelig.

Safe

En af de største syndere i Java programmering, der får programmer til at crashe og kan give programmører grå hår er NullPointerException. I Java kan alle Objects sættes til null og hvis et metodekald eksekveres på et object der er null, kastes en NullPointerException.

 
 Java Nullpointer exception, der kan undgås i Kotlin Andorid app udvikling.
 

Hvilket kan lede til en eksplosion af null-checks:

if ( persons != null && persons.get( 0 ) != null && persons.get( 0 ).getName( ) != null ) {
	System.out.println( “The person’s name is “ + persons.get( 0 ).getName( ) )
} else {
	System.out.println( “The person’s name is John Doe“)
}

Kotlin har sat null ind i dets ‘type hierarchy’, så programmøren er tvunget til at håndtere null, mens han koder. I Kotlin skal man specificere om en værdi kan være null ved at tilføje et ‘?’ efter typen:

var a: Person = null // Compile error
var b: Person? = null // Ok


Når compileren ser at der er et metodekald på person ‘b’, ved compileren at personen er af type nullable og godkender først programmet, når programmøren har håndteret, at personen kan være null. Dette kan gøres i Kotlin ved at bruge safe-check operatøren ‘?.’, hvis object’et er null sender den null tilbage i stedet for at kalde næste metode, som ville have ført til et crash.

Som et eksempel kan Java koden ovenfor omskrives til:

println ( “The person’s name is ${ persons?.get(0)?.name ?: “John Doe”} ” )

Først i eksemplet bemærkes det at der gøres brug af Kotlins String template til at indsætte kode direkte i strengen ved hjælp af ${ … }, så strengen ikke skal fragmenteres med kodestumper imellem hvert fragment, som i Java. Dernæst er Elvis operatoren ‘?:’ tilføjet, der evaluerer udtrykket og returnere resultatet, hvis det ikke er null. Evalueres udtrykket til null indsættes værdien til højre for operatoren i stedet.

Hver gang man skal referere til en variable der kan være null, skal man i Kotlin bruge safe-check operatoren. Hvis det er den samme variable der bruges hver gang og der er tjekket på at den ikke er null, kan compileren instrueres i, at den ikke kan være null længere.

  • Java metoden: “if ( b != null ) { … }

  • Kotlin metoden: b?.let{ person ->  … } 

Begge metoder virker i Kotlin, og valget ligger hos den enkelte programmør, hvilken der bruges. Kotlin metoden tjekker om ‘b’ er forskellig fra null og eksekverer derefter kodenblokken inde i ‘let’ operatoren.

Interoperability with Java

Under opbyggelsen af Kotlin sproget, har der været fokus på, at det skal kunne arbejde sammen med Java, hvilket har resulteret i, at Java klasser kan kalde metoder i Kotlin klasser og omvendt. Ved omskiftelse fra Java til Kotlin er det muligt at have Java og Kotlin klasser i samme projekt. En mulig overgang til Kotlin kan derfor opnås gennem videreudvikling i et fungerende Java projekt, hvor der ved fremtidige opgaver oprettes Kotlin klasser i stedet for Java klasser.

Access Views by Id

Med Kotlin kan du sige farvel til Butterknife og findViewById. Plugin’et ‘kotlin.android.extensions’ gør det muligt at referere views direkte i kildekoden. 

1. Plugin’et skal tilføjes i gradle filen.

apply plugin: 'kotlin-android-extensions'

2. Giv det view der skal refereres et id.

<TextView
    android:id="@+id/hello_text"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    />

3. Importer id’erne fra den relevante layout fil, hvilket muliggør at opdatere view’et direkte i kildekoden.

import kotlinx.android.synthetic.main.fragment_dashboard.*
hello_text?.text = “Hello Kotlin!”

Konklusion

Kotlin leverer et sprog, hvor boilerplate kode minimeres, samt mindsker skjulte NullPointerExceptions ved at integrere null i dets “type hierarchy”. Ydermere er sproget Interoperable med Java, hvilket muliggør at introducere kotlin i kørende projekter uden at omskrive hele projektet.

Kotlin har mange lækre features, hvor sugercoating af at referere XML filerne direkte i kildekoden kun er en smagsprøve. Læs mere om Kotlin’s features i næste blogpost, der omhandler higher order functions, extension methods og method overloading.

Af Lasse Sørensen

Android Udvikler hos Touchlogic