Throw/Throws — nedir, istisna fırlatma operatörleri ve mobil geliştirmede nasıl çalışır

Yazar: IT Sectr Yayınlanma: 2026-05-26 Okuma süresi: 9 dk

Throw ve Throws, programlama dillerinde istisnaları fırlatma ve bildirme mekanizmalarıdır. throw operatörü, bir fonksiyonun normal yürütmesini kesintiye uğratır ve hata nesnesini çağrı yığınında yukarı gönderir. Fonksiyon imzasındaki throws anahtar kelimesi, çağıran tarafı bir hata olasılığı konusunda uyararak kodu öngörülebilir hale getirir. Kotlin Dokümantasyonu (2026)'na göre, Kotlin'de throw bir ifade (expression)dir, bir değil, bu da onun when blokları ve Elvis operatörü içinde kullanılmasına olanak tanır.

Önemli Noktalar

  • Throw — fonksiyon yürütmesini kesintiye uğratan ve hata nesnesini çağrı yığınında yukarı gönderen bir operatör
  • Throws — fonksiyonun bir istisna fırlatabileceğini bildiren, fonksiyon imzasındaki bir anahtar kelime
  • Swift'te fonksiyon throws ile işaretlenir, çağrı try/try?/try! gerektirir ve throw, Error protokolünü uygulayan her türü kabul eder
  • Kotlin'de throw, Nothing türünde bir ifadedir, throws yoktur (tüm istisnalar unchecked'tır)
  • Özel hatalar, catch'te kolay kullanım için enum (Swift) veya sealed class (Kotlin) aracılığıyla oluşturulur

Throw ve Throws Nedir?

Throw, program yürütme noktasında bir istisna oluşturan bir operatördür. throw ile karşılaşıldığında, mevcut yürütme akışı derhal kesintiye uğrar ve kontrol, çağrı yığınındaki en yakın catch işleyicisine aktarılır. Hiçbir işleyici bulunamazsa, uygulama çöker. Mobil geliştirmede throw, mevcut soyutlama düzeyinde işlenemeyen hataları (geçersiz sunucu yanıtı, ağ yokluğu veya yanlış argümanlar) bildirmek için kullanılır.

Throws — bir fonksiyon imzasındaki değiştirici (temel olarak Swift'te) fonksiyonun bir hata fırlatabileceğini bildirir. Bu, Swift'teki checked hata mekanizmasının bir parçasıdır: çağıran taraf, hatayı do-catch, try?, try! aracılığıyla işlemek veya daha fazla yayılım için kendi fonksiyonunu throws olarak işaretlemek zorundadır. Kotlin ve Java'da throws da mevcuttur, ancak Kotlin bunu gereksiz görür — Kotlin'deki tüm istisnalar unchecked'tır, yani sözdizimsel zorlama olmadan işlenmeyebilirler. Apple Swift Dokümantasyonu (2026)'na göre, Swift'te throws, fonksiyon türünde bir hata olasılığını açıkça bildirmenin tek yoludur ve API sözleşmelerini geliştirici için şeffaf hale getirir.

throw ve throws arasındaki fark temeldir: throw bir eylemdir (çalışma zamanında istisna fırlatmak), throws bir bildirimdir (derleme zamanı sözleşmesi). throws olmayan bir fonksiyon throw kullanamaz — Swift derleyicisi bir hata üretecektir. throws olan bir fonksiyon throw kullanmayabilir — buna izin verilir ancak anlamsızdır. Bu ayrım, throw/throws'u güçlü bir API tasarım aracı haline getirir; burada hata sözleşmesi, fonksiyon çağrılmadan önce imzasında görünür.

Swift'te Throw

Swift'te, throw operatörü Error protokolünü uygulayan her türü kabul eder. En yaygın olarak, farklı hata türleri için durumları olan bir enum'dur. Swift, Java tarzı checked istisnaları desteklemez — bunun yerine, fonksiyon türü throws ile işaretlenir ve işleme çağıran tarafa devredilir. Bu, Swift'te throw'u daha esnek hale getirir ancak geliştirici için daha fazla sorumluluk da getirir.

Error Protokolü ve Hata Türleri

Error protokolüne uyan her tür, throw aracılığıyla fırlatılabilir. Geliştiriciler çoğunlukla basit hatalar için ilişkili değeri olmayan veya bağlam iletmek için ilişkili değerleri olan bir enum kullanır. Swift, hatanın bir enum olmasını gerektirmez — Error'u uygulayan bir struct veya class kullanabilirsiniz, ancak işleyici tarafındaki exhaustive switch sayesinde enum tercih edilir. Derleyici, do-catch'te tüm durumların işlendiğini kontrol eder.

swift
enum AuthError: Error {
    case invalidCredentials
    case tokenExpired
    case accountLocked(remainingMinutes: Int)
}

func login(username: String, password: String) throws -> Session {
    guard isValid(username) else {
        throw AuthError.invalidCredentials
    }
    let response = try api.authenticate(username, password)
    if response.isLocked {
        throw AuthError.accountLocked(
            remainingMinutes: response.lockDuration
        )
    }
    return Session(token: response.token)
}

AuthError üç senaryo tanımlar: geçersiz kimlik bilgileri, süresi dolmuş token ve remainingMinutes ilişkili değerine sahip kilitli hesap. login fonksiyonu throws olarak bildirilir — derleyici onu try aracılığıyla çağırmayı gerektirir. Fonksiyon içinde, throw iki yerde kullanılır: geçersiz bir kullanıcı adı için ve kilitli bir hesap için. İlişkili değer accountLocked, kullanıcıya somut veriler (kilidin açılması için kaç dakika beklenmesi gerektiği) iletmeye olanak tanır. Bu yaklaşım, kilit durumunu kontrol etmek için ayrı API uç noktalarına olan ihtiyacı ortadan kaldırır.

Kotlin'de Throw

Kotlin'de throw, Nothing türünde bir ifadedir, bir değil. Bu, throw'un bir atamanın sağ tarafında, when ifadeleri içinde ve Elvis operatörü ?: içinde kullanılabileceği anlamına gelir. Nothing türü, Kotlin'deki tüm türlerin özel bir alt türüdür ve throw'un herhangi bir türde değerin gerektiği yerlerde kullanılmasına olanak tanır. Derleyici, throw'dan sonra yürütmenin devam etmediğini anlar ve bu durum için bir dal gerektirmez.

Nothing Türü ve Kompozisyondaki Rolü

Nothing, Kotlin'de tüm olası türlerin alt türü olan benzersiz bir tür. Nothing döndüren bir fonksiyon (orneğin TODO()) asla normal şekilde tamamlanmaz — ya her zaman bir istisna fırlatır ya da sonsuz döngüye girer. Bu, throw'u bir değerin gerekli olduğu yerlerde (Elvis operatörü, else'siz when, değişken başlatma) kullanım için doğal bir aday haline getirir. throw bir when dalındaysa, derleyici dalın Nothing'e gittiğini anlar ve bu dal için return veya else gerektirmez.

kotlin
data class Config(val apiUrl: String, val timeoutSec: Int)

class ConfigParser {
    fun parse(json: String): Config {
        val obj = JSONObject(json)
        val url = obj.optString("apiUrl")
            ?: throw IllegalArgumentException("apiUrl is required")
        val timeout = obj.optInt("timeoutSec", 30)
        return Config(url, timeout)
    }

    fun getErrorMessage(code: Int): String {
        return when (code) {
            404 -> "Not found"
            500 -> "Server error"
            else -> throw IllegalArgumentException("Unknown code: $code")
        }
    }
}

İlk örnekte, throw Elvis operatörü ?: içinde kullanılır: JSON'da apiUrl alanı yoksa, throw ifadesi derhal yürütmeyi kesintiye uğratır ve bir IllegalArgumentException fırlatır. Nothing türü, derleyicinin sağ tarafın türünü String olarak çıkarmasına olanak tanır (Elvis String bekler, throw Nothing türündedir, Nothing String'in alt türüdür). İkinci örnekte, bir when ifadesi içinde throw: kod bilinen hiçbiriyle eşleşmezse, bir istisna fırlatılır. Derleyici, throw'dan sonraki kodun erişilemez olduğunu anlar, bu nedenle fonksiyonun dönüş türü String ihlal edilmez.

Fonksiyon İmzasında Throws ve rethrows

Swift'te throws, parametre listesinden sonra ve dönüş türü okundan önce belirtilir. throws olan bir fonksiyon, yalnızca do-catch içinde veya try? ile diğer throws fonksiyonlarını çağırabilir. Bir throws fonksiyonu hatayı işlemezse, onu çağıran tarafa iletir. Swift ayrıca rethrows'u da destekler — bir throws closure kabul eden ve hatasını yayan üst düzey fonksiyonlar için bir değiştirici. rethrows, fonksiyonun yalnızca iletilen closure bir hata fırlattıysa hata fırlattığı anlamına gelir — fonksiyonun kendisi bir hata oluşturmaz.

swift
func mapValues<T>(
    _ array: [T],
    transform: (T) throws -> U
) rethrows -> [U] {
    var result = [U]()
    for element in array {
        result.append(try transform(element))
    }
    return result
}

// throws closure ile kullanım
let parsed = try mapValues(jsonStrings) { str in
    let data = Data(str.utf8)
    return try JSONDecoder().decode(Item.self, from: data)
}

rethrows, mapValues fonksiyonunun esnek olmasını sağlar: hem throws closure'ları hem de normal closure'ları kabul eder. Bir throws closure iletilirse, mapValues çağrısı try gerektirir; normal ise try gerekmez. Bu, rethrows'u Swift standart kütüphanesindeki map, filter, reduce gibi üst düzey fonksiyonlar için ideal hale getirir. Apple Önerisi: throws closure'ları kabul eden ve tek hata kaynağı bu closure olan API'ler için rethrows kullanın. Fonksiyon kendi hatasını fırlatabiliyorsa, throws kullanın.

Checked ve unchecked istisnalar

Swift throws, checked istisnalara (Java'daki gibi) daha yakındır — fırlatılan hatalar imzada bildirilir. Kotlin ve Dart unchecked istisnalar kullanır — imzada throws gerekli değildir. Fark temeldir: checked, geliştiriciyi hatayı işlemeye zorlar (daha güvenli ancak daha ayrıntılı), unchecked özgürlük verir ancak bir hatayı işlemeyi unutma riskini artırır. Swift throws için checked'u seçti, Kotlin tüm istisnalar için unchecked'u seçti. Her iki yaklaşımın da avantajları vardır: Swift dil düzeyinde daha güvenilirdir, Kotlin daha kompakt ve işlevsel dönüşüm zincirlerinde kullanışlıdır.

Özel Hata Türleri

Mobil uygulamalarda yapılandırılmış hata işleme için, temel Exception veya Error kullanmak yerine özel hata türleri oluşturulması önerilir. Swift'te bunun için Error protokolü ile bir enum kullanılır; Kotlin'de Throwable'dan (veya Exception'dan) miras alan bir sealed class; Dart'ta Exception'dan miras alan bir class. Özel türler, hataları kategorilere göre gruplamaya ve ilişkili verileri iletmeye olanak tanır.

DilHata türüÖzellik
Swiftenum: Error { ... }İlişkili değerler, catch'te exhaustive switch
Kotlinsealed class : Throwable()Alanları olan hatalar için Data class, when ifadesi
Dartclass implements ExceptionMessage alanı, catch'te on yan tümcesi
Javaclass extends ExceptionChecked vs unchecked, imzada zorunlu throws

Özel hatalar tasarlarken şu kuralı izleyin: bir hata — bir senaryo. Farklı nedenleri String message işaretli tek bir türde birleştirmeyin — her senaryo için ayrı durumlar/alt sınıflar oluşturun. Bu, çağıran tarafın her durumu dize karşılaştırması yerine örüntü eşleme (when/switch) aracılığıyla işlemesine olanak tanır. Swift'te bu, exhaustive checking sağlar — NetworkError enum'unun herhangi bir durumu işlenmezse derleyici uyarır.

Kotlin'de özel hata örneği

kotlin
sealed class NetworkError(val message: String) : Throwable(message) {
    data class Timeout(val durationMs: Long) :
        NetworkError("Request timed out after ${durationMs}ms")
    data class HttpError(val code: Int, val body: String?) :
        NetworkError("HTTP $code")
    data class NoConnection(val cause: IOException) :
        NetworkError("No internet connection")
}

Sealed class NetworkError, Throwable'dan (Kotlin'deki standart istisna türü) miras alır. Her alt sınıf, kendi alanlarına sahip bir data class'tır: Timeout, milisaniye cinsinden zaman aşımı süresini içerir, HttpError, kodu ve yanıt gövdesini içerir, NoConnection, orijinal IOException'u içerir. Bu tasarım, her hatanın when aracılığıyla kapsamlı eşleme ile işlenmesine olanak tanır (yeni bir alt sınıf eklediğinizde, derleyici tüm when ifadelerini güncellemeye zorlar).

Swift'te Try, try? ve try!

Swift, throws fonksiyonlarını çağırmak için her biri kendi güvenlik sözleşmesine sahip üç yol sunar. try standart yoldur: do-catch gerektirir veya bir throws fonksiyonu içinde olmayı gerektirir. try? hatayı nil'e dönüştürür — sonuç isteğe bağlı hale gelir, hata durumunda nil döndürür, tür T'den T?'ye değişir. try! — işlemesiz zorunlu yürütme: bir hata fırlatılırsa, uygulama çöker. try!'yi yalnızca bir hatanın imkansız olduğundan kesinlikle emin olduğunuzda kullanın (orneğin, açıkça geçerli veriler).

swift
let configPath = Bundle.main.path(forResource: "config", ofType: "json")!

// try? — isteğe bağlı sonuç
let data = try? Data(contentsOf: URL(fileURLWithPath: configPath))
let json = try? JSONSerialization.jsonObject(with: data ?? Data())

// try! — garanti edilen başarı (yalnızca emin olduğunuzda)
let decoder = JSONDecoder()
let defaultConfig = try! decoder.decode(
    Config.self,
    from: Config.defaultJSON
)

// try — standart işleme
do {
    let user = try fetchUser()
    showUser(user)
} catch let error as NetworkError {
    showRetryAlert(error.message)
}

Örnekte, try! uygulama paketine gömülü açıkça geçerli JSON için kullanılır — doğru bir sürümde kod çözme hatası imkansızdır. try? bir yapılandırma dosyasını okumak için kullanılır — dosya eksik veya bozuksa, uygulama çökmek yerine varsayılan değerleri kullanır. do-catch içindeki try, bir hatanın beklendiği ve kullanıcı yanıtı gerektiren ağ istekleri için kullanılır. Öneri: üretim kodunda try!'den kaçının — yalnızca derleme zamanında doğrulanmış sabit veriler için kullanın.

Sıkça Sorulan Sorular

Swift'te throw ve throws arasındaki fark nedir?

Throw, program yürütmesi sırasında bir hata fırlatarak akışı kesintiye uğratan bir operatördür. Throws, fonksiyonun bir hata fırlatabileceğini bildiren bir fonksiyon imza değiştiricisidir. throws olmayan bir fonksiyon throw kullanamaz. Throws bir derleme zamanı sözleşmesidir, throw bir çalışma zamanı eylemidir.

Kotlin'de neden throws yok?

Kotlin, unchecked istisnalar felsefesini izler: tüm istisnalar sözdizimsel zorlama olmadan işlenmeden kalabilir. Kotlin geliştiricileri, Java'daki throws'un aşırı try-catch bloklarına ve boş catch aracılığıyla checked istisnaların görmezden gelinmesine yol açtığına inanır. Kotlin'in Nothing türü, throw'un bir ifade olarak kullanılmasına olanak tanır ve throws'u daha esnek bir yaklaşımla değiştirir.

Swift'te try! ne zaman kullanılmalı?

try! yalnızca bir hatanın imkansız olduğundan kesinlikle emin olduğunuzda kabul edilebilir: paketten açıkça geçerli JSON, sabit veriler, doğru URL şemaları. Üretim kodunda try! bir istisnadır, kural değil. try? bir geri dönüş değeri olan isteğe bağlı senaryolar için tercih edilir, zorunlu hata işleme için try ile do-catch kullanılır.

Swift'te rethrows nedir?

Rethrows, throws closure'ları kabul eden fonksiyonlar için bir değiştiricidir. rethrows olan bir fonksiyon, yalnızca iletilen closure bir hata fırlattıysa hata fırlatır. Bu, üst düzey fonksiyonların (map, filter) çağıran tarafta try'yi zorlamadan hem throws hem de throws olmayan closure'larla çalışmasına olanak tanır.

Bir catch bloğu içinde hata fırlatılabilir mi?

Evet, catch içinde hatayı farklı bir türe sararak veya bağlam ekleyerek yığında yukarı yaymak için throw kullanabilirsiniz. Buna hata zincirleme veya yeniden fırlatma denir. Swift'te, catch içinde başka bir throw yeterlidir; Kotlin'de, bir catch bloğu içinde throw. finally bloğu, kontrol daha ileri iletilmeden önce yürütülür.

Özet

  • Throw — mevcut akışı kesintiye uğratan ve hata nesnesini yığında yukarı gönderen bir istisna fırlatma operatörü
  • Throws — fonksiyon imzasında bir hata olasılığı hakkında derleme zamanı bildirimi, Swift'te zorunlu, Kotlin'de yok
  • Swift'te throw enum: Error kabul eder, fonksiyon throws ile işaretlenir, try / try? / try! ile çağrılır
  • Kotlin'de throw, Nothing türünde bir ifadedir, when, Elvis operatörü ve atamalarda kullanılmasına olanak tanır
  • Swift'te Rethrows, üst düzey fonksiyonların yalnızca iletilen closure'lardan hataları yaymasına olanak tanır
  • Özel hatalar, ayrıntılı bilgi için ilişkili değerlerle enum (Swift) veya sealed class (Kotlin) aracılığıyla oluşturulur
  • Örüntü eşleme aracılığıyla kolay kullanım için "bir durum — bir senaryo" ilkesine göre hata türleri tasarlayın

Anahtar teslim bir mobil uygulama geliştireceğiz

IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.

Projeyi tartış

Ayrıca okuyun