Android Uygulama Geliştirme : Kotlin vs. Java

Abdullah Turan MERALER
KoçSistem
Published in
4 min readJul 23, 2019

Google’ın Mayıs 2017 de yapılan Google I/O etkinliğinde ilk defa birinci seviyede destek verdiği diller arasında duyurduğu Kotlin; Android Studio’nun da geliştiricisi olan JetBrains tarafından geliştirilmiş yeni nesil bir programlama dili. Söz dizilimi (syntax) olarak çağdaşı kabul edilebilecek olan Swift’e oldukça yakın bir dil. Android uygulama geliştirmeye uygunluğunun temel sebebi olarak Java Virtual Machine (JVM) üzerinde koşuyor olması. Her iki dilin de JVM üzerinde koşuyor olması sayesinde daha önce Java ile geliştirmeye başlanmış olan bir projeyi oldukça rahat bir şekilde yeni sınıflarını Kotlin ile yazmaya devam edilebiliyor.

İki yazılım dilininin ortaya çıkış zamanı arasındaki ciddi bir fark var. Yalnızca bu noktadan bile tahmin edilebileceği gibi Kotlin, Java’ya göre geliştiriciler açısından çok daha konforlu bir dil. Öncelikle bu konforu oluşturan ana başlıklara kısaca değinip devamında bu unsurları daha detaylı inceleyeceğiz. Öne çıkan konu başlıkları :

  1. Extension function yazmak oldukça kolaydır. Herhangi bir sınıfa ek olarak fonksiyon yazmak ihtiyacınız olduğunda bu sınıfı extend eden bir sınıf daha yazmanıza ihtiyaç yoktur.
  2. Daha az kod yazarak işi bitirmenizi sağlar. Java’da koca bir sınıf yazmanız gerekirken aynı işi Kotlin’de bir kaç satır ile yapabilirsiniz.
  3. Daha güvenlidir. Özellikle NullPointerException almanız Java’ya göre zordur. Null olabilecek caseleri düzenlemeniz için Kotlin geliştiriciyi zorlar.
  4. Java ile uyumludur. Kotlin ile geliştirme yaptığınızda, Java ile geliştirirken kullandığınız 3rdParty kütüphanelerinin neredeyse tamamını kullanmaya devam edebilirsiniz. Aynı zamanda istediğiniz sınıfı Java ile yazabilir ve Kotlin sınıfları içinde kullanabilirsiniz.
  5. Fonksiyoneldir. Temelde nesne yönelimli bir dildir. Ancak fonksiyonel dillerin bir çok imkanından ve konseptinden yararlandırmaktadır.

Şimdi yukarıda kısaca değindiğim konuları içeren birkaç karşılaştırma örneğini göstererek bu avantajları daha somut bir şekilde ortaya koymaya çalışacağım.

Extension

Önce Java ile yaptığı tek iş ekrana “Bir hata oluştu” diye Toast mesajı basan metodu AppCompatActivity sınıfına extend etmeyi deneyeceğim. Görüldüğü gibi önce AppCompatActivity’i extend eden bir sınıf oluşturmam ve metodu bu sınıfın içerisine yazmamız gerekiyor.

public class ExtendedToast extends AppCompatActivity {

public void errorToast()
{
Toast.makeText(this,"Bir hata oluştu", Toast.LENGTH_LONG).show();

}
}

Tabi ki bu fonksiyonu kullanabilmem için bu sınıfı da başka bir yerde extend etmemiz gerekiyor.

class TheOtherActivity : ExtendedToast() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_the_other)
setSupportActionBar(toolbar)


fab.setOnClickListener { view ->
errorToast()

}
}

}

Peki bu işlemi Kotlin ile nasıl yapıyoruz ?

class MainActivity : AppCompatActivity() {

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

fab.setOnClickListener { view ->
errorToast()
}
}


fun AppCompatActivity.errorToast() {
Toast.makeText(this,"Bir hata oluştu",Toast.LENGTH_LONG).show()

}
}

Çalıştığımız sınıf içinde yalnızca bir metod ekleyerek aynı işlemi yapmış oldum. Tanımlama sırasında metot ismi olarak AppCompatActivity.errorToast() yazarak ihtiyacımızı karşılamış olduk. Tam manasıyla Java ile iki sınıfta yapılabilen iş Kotlin ile iki satırda halledilmiş oldu.

Kod miktarı

Bu konuda uygulama geliştirirken kullanmamız kaçınılmaz olan Custom Data Modeller üzerinden örnek vereceğin. Diyelim ki içinde üç tane alan olan bir Person nesnesine ihtiyacımız var. Bu nesneyi Java ile aşağıdaki gibi modelleyebiliriz.

public class Person {
private String name;
private String surname;
private int age;

public Person(String name, String surname, int age) {
this.name = name;
this.surname = surname;
this.age = age;
}

public String getName() {
return name;
}

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

public String getSurname() {
return surname;
}

public void setSurname(String surname) {
this.surname = surname;
}

public int getAge() {
return age;
}

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


@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Person)) return false;
Person person = (Person) o;
return age == person.age &&
name.equals(person.name) &&
surname.equals(person.surname);
}

@Override
public int hashCode() {
return Objects.hash(name, surname, age);
}

@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", surname='" + surname + '\'' +
", age=" + age +
'}';
}
}

Aynı nesneyi Kotlin ile oluşturmak için yazılması gereken kod ise burada:

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

Sınıfın başına yalnızca data anahtar kelimesini eklediğinizde Kotlin arka tarafta üstteki Java sınıfında görmüş olduğunuz bütün fonksiyonları sizin için hazırlar. Tabi ki bununla sınırlı değilsiniz sınıfın içine özelleştirmek istediğiniz fonksiyonu override etmenize ve kendi ihtiyacınıza göre özelleştirmenize izin verir.

Güvenlik

Kotlin’de değişken tanımlama mantığı Java’dan farklıdır. Oluşturduğunuz nesnenin null olabilirliğini sağlamak için özel anahtar kelime kullanmanız gerekir. Bu sayede uygulama çalışırken NullPointerException alma riski oldukça azalır. Birkaç örnekle göstermeye çalışacağım:

var person : Person = null

yukarıdaki gibi bir tanımla ile Kotlin, compile sırasında hata verir.Hata vermemesi için bu satırın aşağıdaki gibi yazılması gerekir.

var Person =  Person("Abdullah Turan","Meraler",28)

özel olarak parametrenin başına lateinit keyword’ünü eklemediğiniz sürece tanımladığınız değişkeni initilaze etmek veya null olabileceğiniz belirtmek için değişken tipininin sonuna ‘?’ karakteri de koyabilirsiniz. Aşağıdaki gibi tanımlama gereklidir.

var person : Person? = null

Bunun dışında bir de parametrenin kullanımı sırasında zorunluluklar var. Bir değişkenin NullPointerException fırlatma riski olduğunda sizi buna karşı önlem almaya zorlar.

person?.copy()

şeklinde bir komut yazdığınızda yalnızca person nesnesinin null olmaması durumunda kopyalama yapacaktır. Yani Java’daki if(person != null) person.copy(); şekilde yazmamız gereken koda eşittir. Önemli fark yukarıdaki gibi bir kontrolü eklemek zorunda olmamamızdır.

person!!.copy()

şeklinde yazdığımızda ise yalnızca person nesnesinin null olmaması durumunda çalışır diğer durumlarda exception fırlatır.

Görüldüğü gibi Kotlin, geliştiriciyi güvenli kod yazmaya zorladığı gibi exception durumlarını da yönetmeye zorlar.

Bütün yazı boyunca Kotlin’i övdük mutlaka bir dezavantajı olması lazım diye düşüneceksiniz. Tabi ki dezavantajı var. Kotlin ile geliştirdiğiniz uygulamanın compile edilmesi süresi Java’dan “bir miktar” daha uzun. Evet, elle tutulur tek olumsuz yönü buymuş gibi gözüküyor.

Sonuç

Yukarında bütün bu anlattıklarımın sonucunda Kotlin, Android uygulama geliştirirken Java’ya göre oldukça hızlı ve güvenli kod yazımını sağlamaktadır. Bu da geliştirme maliyetini oldukça aşağı çekmektedir. Kotlin’in compile süresinin biraz daha uzun olması tamamen göz ardı edilebilir bir durumdur.

Bu yazıda “Kotlin for Android Developers,Antonio Leiva,2017” kitabı referans alınmıştır.

https://leanpub.com/kotlin-for-android-developers

--

--