Sobes.tech
Junior

Kotlin'de istisnaları nasıl doğru şekilde işleriz?

sobes.tech yapay zeka

AI'dan gelen yanıt

Kotlin'de istisna yönetimi try...catch...finally yapısı kullanılarak yapılır. Java kodu ile etkileşim için @Throws ile işaretlenmiş fonksiyonlar çağrılabilir.

fun readFile(path: String): String {
    return try {
        // Tehlikeli kodu çalıştırmaya çalışma
        java.io.File(path).readText()
    } catch (e: java.io.IOException) {
        // Belirli bir istisnayı işleme
        println("Dosya okunurken hata: ${e.message}")
        "" // Hata durumunda varsayılan değer döndür
    } finally {
        // Her zaman çalıştırılan blok
        println("Dosya okuma işlemi tamamlandı")
    }
}

Farklı istisna türlerini işlemek için birden fazla catch bloğu kullanılabilir:

fun processData(data: String) {
    try {
        // NumberFormatException veya NullPointerException oluşturabilecek kod
        val number = data.toInt()
        println("Sayı: $number")
    } catch (e: NumberFormatException) {
        println("Geçersiz sayı formatı: ${e.message}")
    } catch (e: NullPointerException) {
        println("Null veriler alındı: ${e.message}")
    }
}

Kotlin, Java gibi checked istisnaları içermez. Fonksiyonlar @Throws kullanarak istisna atabileceğini bildirebilir, ancak bu Kotlin kodunda zorunlu değildir.

İşlevin başarıyla veya hata ile tamamlanabileceği durumlar için, genellikle sealed sınıflar veya Kotlin'in deneme sürümlerinde bulunan Result tipi kullanılır, özellikle asenkron kodlarda.

Sealed sınıf örneği:

sealed class Result<out T>
data class Success<out T>(val value: T) : Result<T>()
data class Error(val exception: Throwable) : Result<Nothing>()

fun safelyDivide(a: Int, b: Int): Result<Int> {
    return try {
        if (b == 0) {
            throw ArithmeticException("Sıfıra bölme")
        }
        Success(a / b)
    } catch (e: Throwable) {
        Error(e)
    }
}

// Kullanım:
fun processDivision() {
    when (val divisionResult = safelyDivide(10, 0)) {
        is Success -> println("Sonuç: ${divisionResult.value}")
        is Error -> println("Hata: ${divisionResult.exception.message}")
    }
}

Sadece işlenebilir istisnaları yakalamak önemlidir. Boş catch bloklarından kaçınılmalıdır. Gerekirse, istisna loglara kaydedilebilir.

Ayrıca, throw anahtar kelimesi kullanılarak açıkça istisna atılabilir:

fun requirePositive(number: Int) {
    if (number <= 0) {
        throw IllegalArgumentException("Sayı pozitif olmalı")
    }
}