Světýlkův blog

Další pohled na věc
  • Můj TaskMan je tzv. Prideware. Jsem na něho pyšný, a proto ho podsouvám všem okolo.

  • Šolichátor. –Pavel K.

  • Lateinit v Kotlinu a jeho výhoda oproti NullPointerException

    Kotlin občas na úrovni byte kódu generuje různý boilerplate, např. v podobě checků inicializace lateinit proměnných, a až donedávna mi unikala jednoduchá, avšak svým významem docela důležitá věc. Říkal jsem si, že pokud aplikace padne na NullPointerException v Javě, anebo na UninitializedPropertyAccessException v Kotlinu, tak že je to v důsledku totéž. Nicméně je zde jeden případ, kdy lateinit jednoznačně vede. Mějme tento kód v Javě:

    package com.svetylkovo.kotlin.lateinit;
    
    public class WithoutLateinit {
        private static String first;
        private static String second;
    
        public static void main(String[] args) {
            first = "First!";
            System.out.println("Total length is "+ String.valueOf(first.length() + second.length()));
        }
    }
    

    Pokud tento kód spustíme, dostaneme:

    Exception in thread "main" java.lang.NullPointerException
    at com.svetylkovo.kotlin.lateinit.WithoutLateinit.main(WithoutLateinit.java:9)

    Po nalezení řádku kódu, kde NullPointerException nastal, si můžeme jen lámat hlavu, která z těch dvou proměnných vlastně null byla a často (v reálných aplikacích) na to musíme ne-zcela triviálním způsobem přijít. Zkusme si stejnou situaci nasimulovat v Kotlinu s pomocí lateinit:

    package com.svetylkovo.kotlin.lateinit
    
    object LateinitTest {
        lateinit var first: String
        lateinit var second: String
    
        @JvmStatic
        fun main(args: Array<String>) {
            first = "First!"
            println("Total length is ${first.length + second.length}")
        }
    }
    

    Když spustíme tento kód, aplikace padne na:

    Exception in thread "main" kotlin.UninitializedPropertyAccessException: lateinit property second has not been initialized
    at com.svetylkovo.kotlin.lateinit.LateinitTest.main(LateinitTest.kt:10)

    kde stacktrace mluví za vše a místo toho, abych teprve začal hledat, co se vlastně stalo špatně, okamžitě vím, že to byla proměnná second, kterou jsem z nějakého (v tomto případě záměrného) důvodu zapomněl inicializovat.

    Posuďte sami, krom toho, že nás Kotlin dokáže NullPointerException zbavit již za překladu téměř úplně, nebylo by lepší v případech, kdy už by tato výjimka musela nastat, dostávat raději UninitializedPropertyAccessException s přesným popisem viníka, který za to může? 🙂

  • V zimě se i z obyčejného chodníku stává parkourové hřiště.

  • Kde je nalitej chlast, tam jsem nalitej já.

  • Když jsi nemocný nebo nakažený déle jak 4 týdny, tak už to není nemoc, ale symbióza.

  • Já to sejdu, protože na tom nesejde.

  • Sušenky jsou, můžem začít. –Martin P.

  • PowerPoint je nejlepší programovací jazyk. Tam jde napsat úplně všechno. –Daniel B.

  • Jestli tam jedou na Cobolu, tak to by mohla být firma, která vymře po meči. –Vladimír M.