Throw/Throws — co to je, operátory vyhazování výjimek a jak fungují v mobilním vývoji

Autor: IT Sectr Publikováno: 2026-05-26 Doba čtení: 9 min

Throw a Throws — mechanismy vyhazování a deklarace výjimek v programovacích jazycích. Operátor throw přerušuje normální provádění funkce a předává objekt chyby nahoru zásobníkem volání. Klíčové slovo throws v signatuře funkce varuje volající stranu o možnosti chyby, činící kód předvídatelným. Podle Kotlin Documentation (2026) je throw v Kotlinu výraz (expression), nikoli příkaz, což umožňuje jeho použití uvnitř when-bloků a elvis operátoru.

Hlavní body

  • Throw — operátor přerušující provádění funkce a předávající objekt chyby nahoru zásobníkem volání
  • Throws — klíčové slovo v signatuře funkce deklarující, že funkce může vyhodit výjimku
  • Ve Swiftu je funkce označena throws, volání vyžaduje try/try?/try!, a throw přijímá jakýkoli typ implementující protokol Error
  • V Kotlinu throw — výraz typu Nothing, throws neexistuje (všechny výjimky jsou unchecked)
  • Uživatelské chyby se vytvářejí pomocí enum (Swift) nebo sealed class (Kotlin) pro snadné zpracování v catch

Co je Throw a Throws?

Throw — je operátor, který generuje výjimku v místě provádění programu. Když narazí na throw, aktuální tok provádění je okamžitě přerušen a řízení je předáno nejbližšímu obslužnému prvku catch v zásobníku volání. Pokud obslužný prvek není nalezen, aplikace se abnormálně ukončí. Throw v mobilním vývoji se používá k signalizaci chyb, které nelze zpracovat na aktuální úrovni abstrakce — například nesprávná odpověď serveru, chybějící síť nebo neplatné argumenty.

Throws — modifikátor v signatuře funkce (hlavně ve Swiftu), který deklaruje, že funkce může vyhodit chybu. To je součást mechanismu checked errors ve Swiftu: volající strana je povinna zpracovat chybu prostřednictvím do-catch, try?, try! nebo označit svou funkci throws pro další předání (propagation). V Kotlinu a Javě throws také existuje, ale Kotlin jej považuje za nadbytečný — všechny výjimky v Kotlinu jsou unchecked, to znamená, že mohu zůstat nezpracované bez syntaktického donucení. Podle Apple Swift Documentation (2026) je throws ve Swiftu — jediným způsobem, jak explicitně deklarovat možnost chyby v typu funkce, což činí API kontrakty transparentními pro vývojáře.

Rozdíl mezi throw a throws je zásadní: throw — je činnost (vyhození výjimky za běhu), throws — je deklarace (smlouva v čase kompilace). Funkce bez throws nemůže použít throw — kompilátor Swiftu dá chybu. Funkce s throws nemusí throw použít — to je povoleno, ale nesmyslné. Toto oddělení činí throw/throws mocným nástrojem pro návrh API, kde je smlouva o chybě viditelná v signatuře funkce ještě před jejím voláním.

Throw ve Swiftu

Ve Swiftu operátor throw přijímá jakýkoli typ implementující protokol Error. Nejčastěji je to enum s případy pro různé druhy chyb. Swift nepodporuje checked exceptions ve stylu Javy — místo toho je typ funkce označen throws a zpracování leží na volající straně. To činí throw ve Swiftu flexibilnějším, ale také zodpovědnějším pro vývojáře.

Protokol Error a typy chyb

Jakýkoli typ, který vyhovuje protokolu Error, může být vyhozen pomocí throw. Nejčastěji vývojáři používají enum s případy bez přidružených hodnot (pro jednoduché chyby) nebo s associated values (pro předávání kontextu). Swift nevyžaduje, aby chyba byla enum — lze použít struct nebo class implementující Error, ale enum je upřednostňován díky exhaustive switch na straně obsluhy. Kompilátor kontroluje, že všechny případy jsou zpracovány v do-catch.

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 definuje tři scénáře: neplatné přihlašovací údaje, vypršený token a zablokovaný účet s přidruženou hodnotou remainingMinutes. Funkce login je deklarována jako throws — kompilátor vyžaduje její volání přes try. Uvnitř funkce je throw použito na dvou místech: při neplatném username a při zablokovaném účtu. Přidružená hodnota accountLocked umožňuje předat uživateli konkrétní údaje — kolik minut čekat do odblokování. Tento přístup eliminuje potřebu samostatných API endpointů pro kontrolu stavu blokování.

Throw v Kotlinu

V Kotlinu je throw — výraz (expression) typu Nothing, nikoli přúkaz. To znamená, že throw lze použít na pravé straně přiřazení, uvnitř when výrazů a elvis operátoru ?:. Typ Nothing — speciální podtyp všech typů v Kotlinu, což umožňuje použití throw na místech, kde je vyžadována hodnota libovolného typu. Kompilátor chápe, že po throw provádění nepokračuje a nevyžaduje větev pro tento případ.

Typ Nothing a jeho role v kompozici

Nothing — jedinečný typ v Kotlinu, který je podtypem všech možných typů. Funkce vracející Nothing (například TODO()) se nikdy normálně neukončí — buď vždy vyhodí výjimku, nebo vstoupí do nekonečné smyčky. To činí throw přirozeným kandidátem pro použití na místech, kde je vyžadována hodnota: elvis operátor, when bez else, inicializace proměnné. Pokud je throw ve větvi when, kompilátor chápe, že větev vede k Nothing a nevyžaduje return nebo else pro tuto věev.

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")
        }
    }
}

V prvním příkladu je throw použito v elvis operátoru ?:: pokud pole apiUrl chybí v JSONu, výraz throw okamžitě přeruší provádění a vyhodí IllegalArgumentException. Typ Nothing umožňuje kompilátoru odvodit typ pravé strany jako String (elvis očekává String, throw má typ Nothing, Nothing je podtyp String). Ve druhém příkladu throw uvnitř when výrazu: pokud kód neodpovídá žádnému ze známých, vyhodí se výjimka. Kompilátor chápe, že po throw je kód nedosažitelný, takže návratový typ funkce String není porušen.

Throws v signatuře funkce a rethrows

Ve Swiftu je throws uvedeno za seznamem parametrů a před šipkou návratového typu. Funkce s throws může volat pouze jiné throws funkce uvnitř do-catch nebo s try?. Pokud throws funkce nezpracovává chybu, předá ji volající straně. Swift také podporuje rethrows — modifikátor pro funkce vyššího řádu, které přijímají uzávěr (closure) s throws a propouštějí jeho chybu. Rethrows znamená, že funkce vyhodí chybu pouze pokud předaný uzávěr ji vyhodil — sama funkce chybu negeneruje.

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
}

// Použití s throws-uzávěrem
let parsed = try mapValues(jsonStrings) { str in
    let data = Data(str.utf8)
    return try JSONDecoder().decode(Item.self, from: data)
}

Rethrows umožňuje funkci mapValues být flexibilní: přijímá throws uzávěry i běžné. Pokud je předán throws uzávěr, volání mapValues vyžaduje try; pokud je běžný — try není potřeba. To činí rethrows ideálním pro funkce vyššího řádu jako map, filter, reduce ve standardní knihovně Swiftu. Doporučení Apple: používejte rethrows pro API, která přijímají throws uzávěry a jediným zdrojem chyby je tento uzávěr. Pokud funkce může vyhodit vlastní chybu, použijte throws.

Checked vs unchecked výjimky

Swift throws je bližší checked exceptions (jako v Javě) — vyhozené chyby jsou deklarovány v signatuře. Kotlin a Dart používají unchecked výjimky — throws v signatuře není vyžadováno. Rozdíl je zásadní: checked nutí vývojáře ke zpracování (bezpečnější, ale upovídanější), unchecked dává svobodu, ale zvyšuje riziko zapomenutí zpracovat chybu. Swift zvolil checked pro throws, Kotlin — unchecked pro všechny výjimky. Oba přístupy mají výhody: Swift je spolehlivější na úrovni jazyka, Kotlin je kompaktnější a pohodlnější v řetězcích funkcionálních transformací.

Vlastní typy chyb

Pro strukturované zpracování chyb v mobilních aplikacích se doporučuje vytvářet vlastní typy chyb místo použití základních Exception nebo Error. Ve Swiftu se k tomu používá enum s protokolem Error, v Kotlinu — sealed class s dědičností od Throwable (nebo od Exception), v Dartu — class s dědičností od Exception. Vlastní typy umožňují seskupovat chyby podle kategorií a předávat přidružená data.

JazykTyp chybyVlastnost
Swiftenum: Error { ... }Přidružené hodnoty, exhaustive switch v catch
Kotlinsealed class : Throwable()Data class pro chyby s poli, when výraz
Dartclass implements ExceptionPole Message, klauzule on v catch
Javaclass extends ExceptionChecked vs unchecked, povinný throws v signatuře

Při navrhování vlastních chyb dodržujte pravidlo: jedna chyba — jeden scénář. Nekombinujte různé příčiny v jednom typu s příznakem String message — vytvářejte samostatné případy/podtřídy pro každý scénář. To umožní volající straně zpracovávat každý případ pomocí pattern matching (when/switch), nikoli porovnáváním řetězců. Ve Swiftu to dává exhaustive checking — kompilátor upozorní, pokud některý případ enum NetworkError není zpracován.

Příklad vlastní chyby v Kotlinu

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 dědí od Throwable (standardní typ výjimek v Kotlinu). Každá podtřída je data class s vlastními poli: Timeout obsahuje dobu trvání čekaní v milisekundách, HttpError — kód a tělo odpovědi, NoConnection — původní IOException. Tento návrh umožňuje zpracování každé chyby pomocí when s úplným pokrytím (když přidáte novou podtřídu, kompilátor vás donutí aktualizovat všechny when výrazy).

Try, try? a try! ve Swiftu

Swift nabízí tři varianty volání throws funkcí, každá s vlastní bezpečnostní smlouvou. try — standardní způsob: vyžaduje do-catch nebo být uvnitř throws funkce. try? převádí chybu na nil — výsledek se stává volitelným, při chybě se vrací nil, typ se mění z T na T?. try! — vynucené provedení bez zpracování: pokud je chyba vyhozena, aplikace spadne. Používejte try! pouze když jste naprosto jisti, že chyba je nemožná (například zjevně správná data).

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

// try? — volitelný výsledek
let data = try? Data(contentsOf: URL(fileURLWithPath: configPath))
let json = try? JSONSerialization.jsonObject(with: data ?? Data())

// try! — zaručený úspěch (pouze když jste si jisti)
let decoder = JSONDecoder()
let defaultConfig = try! decoder.decode(
    Config.self,
    from: Config.defaultJSON
)

// try — standardní zpracování
do {
    let user = try fetchUser()
    showUser(user)
} catch let error as NetworkError {
    showRetryAlert(error.message)
}

V příkladu je try! použito pro zjevně platný JSON vložený do bundle aplikace — chyba dekódování je při správném vydání nemožná. try? se aplikuje pro čtení konfiguračního souboru — pokud soubor chybí nebo je poškozen, aplikace použije výchozí hodnoty místo pádu. try v do-catch se používá pro síťové požadavky, kde je chyba očekávána a vyžaduje reakci uživatele. Doporučení: vyhněte se try! v produkčním kódu — vyjímku čiňte pouze pro konstantní data ověřená v průběhu sestavení.

Často kladené otázky

Jaký je rozdíl mezi throw a throws ve Swiftu?

Throw — operátor, který vyhodí chybu během provádění programu a přeruší tok. Throws — modifikátor signatury funkce deklarující, že funkce může vyhodit chybu. Funkce bez throws nemůže použít throw. Throws je smlouva v čase kompilace, throw je činnost za běhu.

Proč v Kotlinu není throws?

Kotlin následuje filozofii unchecked exceptions: všechny výjimky mohou být nezpracované bez syntaktického donucení. Vývojáři Kotlinu se domnívají, že throws v Javě vede k nadbytečným try-catch blokům a ignorování checked exceptions pomocí prázdných catch. Typ Nothing v Kotlinu umožňuje použít throw jako výraz a nahrazuje throws flexibilnějším způsobem.

Kdy použít try! ve Swiftu?

try! je povoleno pouze když jste naprosto jisti, že chyba je nemožná: zjevně platný JSON z bundle, konstantní data, správné URL schéma. V produkčním kódu je try! výjimka, nikoli pravidlo. try? je upřednostňováno pro volitelné scénáře s výchozí hodnotou, try s do-catch pro povinné zpracování chyb.

Co je rethrows ve Swiftu?

Rethrows — modifikátor pro funkce, které přijímají throws uzávěry. Funkce s rethrows vyhodí chybu pouze pokud předaný uzávěr ji vyhodil. To umožňuje funkcím vyššího řádu (map, filter) pracovat s throws i non-throws uzávěry bez vynuceného try na volající straně.

Lze vyhodit chybu uvnitř bloku catch?

Ano, uvnitř catch lze použít throw k propuštění chyby výše v zásobníku, zabalení do jiného typu nebo přidání kontextu. To se nazývá error chaining nebo rethrow. Ve Swiftu stačí další throw uvnitř catch, v Kotlinu — throw uvnitř bloku catch. Blok finally se provede před předáním řízení dále.

Shrnutí

  • Throw — operátor vyhození výjimky, který přeruší aktuální tok a předá objekt chyby nahoru zásobníkem
  • Throws — deklarace v čase kompilace v signatuře funkce o možnosti chyby, povinná ve Swiftu, chybí v Kotlinu
  • Ve Swiftu throw přijímá enum: Error, funkce je označena throws, volána přes try / try? / try!
  • V Kotlinu throw — výraz typu Nothing, umožňující použití v when, elvis operátoru a přiřazeních
  • Rethrows ve Swiftu umožňuje funkcím vyššího řádu propouštět chyby pouze z předaných uzávěrů
  • Vlastní chyby se vytvářejí pomocí enum (Swift) nebo sealed class (Kotlin) s přidruženými hodnotami pro podrobné informace
  • Navrhujte typy chyb podle principu jeden případ — jeden scénář pro snadné zpracování pomocí pattern matching

Vyvineme mobilní aplikaci na klíč

IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.

Prodiskutovat projekt

Přečtěte si také