Throw/Throws — यह क्या है, अपवाद थ्रो ऑपरेटर और मोबाइल डेवलपमेंट में यह कैसे काम करता है

लेखक: IT Sectr प्रकाशित: 2026-05-26 पढ़ने का समय: 9 मिनट

Throw और Throws प्रोग्रामिंग भाषाओं में अपवादों को थ्रो और घोषित करने की क्रियाविधियाँ हैं। throw ऑपरेटर फ़ंक्शन के सामान्य निष्पादन को बाधित करता है और एरर ऑब्जेक्ट को कॉल स्टैक में ऊपर भेजता है। फ़ंक्शन सिग्नेचर में throws कीवर्ड कॉल करने वाले पक्ष को एरर की संभावना के बारे में चेतावनी देता है, जिससे कोड पूर्वानुमानित हो जाता है। Kotlin दस्तावेज़ीकरण (2026) के अनुसार, Kotlin में throw एक अभिव्यक्ति (expression) है, न कि एक निर्देश, जो इसे when-ब्लॉक और एल्विस ऑपरेटर के अंदर उपयोग करने की अनुमति देता है।

मुख्य बातें

  • Throw — एक ऑपरेटर जो फ़ंक्शन के निष्पादन को बाधित करता है और एरर ऑब्जेक्ट को कॉल स्टैक में ऊपर भेजता है
  • Throws — फ़ंक्शन सिग्नेचर में एक कीवर्ड जो घोषित करता है कि फ़ंक्शन एक अपवाद थ्रो कर सकता है
  • Swift में फ़ंक्शन को throws से चिह्नित किया जाता है, कॉल के लिए try/try?/try! की आवश्यकता होती है, और throw Error प्रोटोकॉल को लागू करने वाले किसी भी प्रकार को स्वीकार करता है
  • Kotlin में throw Nothing प्रकार की अभिव्यक्ति है, throws अनुपस्थित है (सभी अपवाद unchecked हैं)
  • कस्टम एरर catch में सुविधाजनक हैंडलिंग के लिए enum (Swift) या sealed class (Kotlin) के माध्यम से बनाए जाते हैं

Throw और Throws क्या है?

Throw एक ऑपरेटर है जो प्रोग्राम निष्पादन के बिंदु पर एक अपवाद उत्पन्न करता है। जब throw का सामना होता है, तो वर्तमान निष्पादन प्रवाह तुरंत बाधित हो जाता है और नियंत्रण कॉल स्टैक में निकटतम catch हैंडलर को स्थानांतरित कर दिया जाता है। यदि कोई हैंडलर नहीं मिलता है, तो एप्लिकेशन क्रैश हो जाता है। मोबाइल डेवलपमेंट में throw का उपयोग उन एरर को संकेत देने के लिए किया जाता है जिन्हें अमूर्तता के वर्तमान स्तर पर संभाला नहीं जा सकता — उदाहरण के लिए, अमान्य सर्वर प्रतिक्रिया, नेटवर्क की अनुपस्थिति या गलत आर्गुमेंट।

Throws — फ़ंक्शन सिग्नेचर में एक संशोधक (मुख्य रूप से Swift में) जो घोषित करता है कि फ़ंक्शन एक एरर थ्रो कर सकता है। यह Swift में checked एरर तंत्र का हिस्सा है: कॉल करने वाला पक्ष do-catch, try?, try! के माध्यम से एरर को संभालने या आगे प्रसार के लिए अपने फ़ंक्शन को throws के रूप में चिह्नित करने के लिए बाध्य है। Kotlin और Java में भी throws मौजूद है, लेकिन Kotlin इसे अनावश्यक मानता है — Kotlin में सभी अपवाद unchecked हैं, अर्थात वाक्यात्मक बाध्यता के बिना उन्हें संभाला नहीं जा सकता। Apple Swift दस्तावेज़ीकरण (2026) के अनुसार, Swift में throws फ़ंक्शन प्रकार में एरर की संभावना को स्पष्ट रूप से घोषित करने का एकमात्र तरीका है, जो डेवलपर के लिए API अनुबंधों को पारदर्शी बनाता है।

throw और throws के बीच अंतर मौलिक है: throw एक क्रिया है (रनटाइम में अपवाद थ्रो करना), throws एक घोषणा है (कंपाइल-टाइम अनुबंध)। बिना throws वाला फ़ंक्शन throw का उपयोग नहीं कर सकता — Swift कंपाइलर एक एरर उत्पन्न करेगा। throws वाला फ़ंक्शन throw का उपयोग नहीं कर सकता — यह अनुमत है लेकिन अर्थहीन है। यह पृथक्करण throw/throws को एक शक्तिशाली API डिज़ाइन टूल बनाता है, जहाँ एरर अनुबंध फ़ंक्शन के कॉल से पहले उसके सिग्नेचर में दिखाई देता है।

Swift में Throw

Swift में, throw ऑपरेटर Error प्रोटोकॉल को लागू करने वाले किसी भी प्रकार को स्वीकार करता है। अक्सर यह विभिन्न प्रकार की एरर के लिए केस वाला एक enum होता है। Swift Java-शैली में checked अपवादों का समर्थन नहीं करता — इसके बजाय, फ़ंक्शन प्रकार को throws से चिह्नित किया जाता है, और हैंडलिंग कॉल करने वाले पक्ष को सौंपी जाती है। यह Swift में throw को अधिक लचीला बनाता है लेकिन डेवलपर के लिए अधिक जिम्मेदारी भी देता है।

एरर प्रोटोकॉल और एरर प्रकार

Error प्रोटोकॉल के अनुरूप कोई भी प्रकार throw के माध्यम से थ्रो किया जा सकता है। अक्सर डेवलपर बिना संबद्ध मान वाले enum (साधारण एरर के लिए) या संबद्ध मान वाले (संदर्भ पास करने के लिए) का उपयोग करते हैं। Swift में एरर का enum होना आवश्यक नहीं है — आप Error लागू करने वाले struct या class का उपयोग कर सकते हैं, लेकिन हैंडलर पक्ष पर exhaustive switch के कारण enum बेहतर है। कंपाइलर जाँचता है कि 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 तीन परिदृश्यों को परिभाषित करता है: अमान्य क्रेडेंशियल, समाप्त टोकन, और remainingMinutes के संबद्ध मान के साथ लॉक किया गया खाता। login फ़ंक्शन throws के रूप में घोषित है — कंपाइलर को इसे try के माध्यम से कॉल करने की आवश्यकता है। फ़ंक्शन के अंदर, throw का उपयोग दो स्थानों पर किया जाता है: अमान्य उपयोगकर्ता नाम के लिए और लॉक किए गए खाते के लिए। संबद्ध मान accountLocked उपयोगकर्ता को विशिष्ट डेटा पास करने की अनुमति देता है — अनलॉक करने से पहले कितने मिनट इंतजार करना है। यह दृष्टिकोण लॉक स्थिति की जाँच करने के लिए अलग-अलग API एंडपॉइंट की आवश्यकता को समाप्त करता है।

Kotlin में Throw

Kotlin में throw Nothing प्रकार की एक अभिव्यक्ति (expression) है, न कि एक निर्देश। इसका मतलब है कि throw का उपयोग असाइनमेंट के दाईं ओर, when-अभिव्यक्तियों के अंदर और एल्विस ऑपरेटर ?: में किया जा सकता है। Nothing प्रकार Kotlin में सभी प्रकारों का एक विशेष उपप्रकार है, जो throw को उन स्थानों पर उपयोग करने की अनुमति देता है जहाँ किसी भी प्रकार के मान की आवश्यकता होती है। कंपाइलर समझता है कि throw के बाद निष्पादन जारी नहीं रहता है और इस मामले के लिए शाखा की आवश्यकता नहीं है।

Nothing प्रकार और संरचना में इसकी भूमिका

Nothing Kotlin में एक अद्वितीय प्रकार है जो सभी संभावित प्रकारों का उपप्रकार है। Nothing लौटाने वाला फ़ंक्शन (उदाहरण के लिए, TODO()) सामान्य रूप से कभी पूरा नहीं होता — या तो हमेशा एक अपवाद थ्रो करता है या अनंत लूप में चला जाता है। यह throw को उन स्थानों पर उपयोग के लिए एक प्राकृतिक उम्मीदवार बनाता है जहाँ मान की आवश्यकता होती है: एल्विस ऑपरेटर, बिना else के when, चर आरंभीकरण। यदि throw किसी when शाखा में है, तो कंपाइलर समझता है कि शाखा Nothing की ओर ले जाती है और उस शाखा के लिए return या else की आवश्यकता नहीं है।

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

पहले उदाहरण में, throw का उपयोग एल्विस ऑपरेटर ?: में किया गया है: यदि JSON में apiUrl फ़ील्ड मौजूद नहीं है, तो throw अभिव्यक्ति तुरंत निष्पादन को बाधित करती है और IllegalArgumentException थ्रो करती है। Nothing प्रकार कंपाइलर को दाईं ओर के प्रकार को String के रूप में अनुमान लगाने की अनुमति देता है (एल्विस String की अपेक्षा करता है, throw का प्रकार Nothing है, Nothing String का उपप्रकार है)। दूसरे उदाहरण में, when-अभिव्यक्ति के अंदर throw: यदि कोड किसी ज्ञात कोड से मेल नहीं खाता है, तो एक अपवाद थ्रो किया जाता है। कंपाइलर समझता है कि throw के बाद कोड अप्राप्य है, इसलिए फ़ंक्शन String का रिटर्न प्रकार उल्लंघन नहीं होता है।

फ़ंक्शन सिग्नेचर में Throws और rethrows

Swift में throws पैरामीटर सूची के बाद और रिटर्न प्रकार तीर से पहले निर्दिष्ट किया जाता है। throws वाला फ़ंक्शन केवल do-catch के अंदर या try? के साथ अन्य throws-फ़ंक्शन कॉल कर सकता है। यदि throws-फ़ंक्शन एरर को संभालता नहीं है, तो वह इसे कॉल करने वाले पक्ष को भेजता है। Swift rethrows का भी समर्थन करता है — उच्च-क्रम फ़ंक्शन के लिए एक संशोधक जो throws क्लोज़र स्वीकार करते हैं और उसकी एरर का प्रसार करते हैं। rethrows का अर्थ है कि फ़ंक्शन केवल तभी एरर थ्रो करता है जब पास किए गए क्लोज़र ने एक थ्रो किया — फ़ंक्शन स्वयं एरर उत्पन्न नहीं करता है।

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-क्लोज़र के साथ उपयोग
let parsed = try mapValues(jsonStrings) { str in
    let data = Data(str.utf8)
    return try JSONDecoder().decode(Item.self, from: data)
}

rethrows mapValues फ़ंक्शन को लचीला बनाता है: यह throws-क्लोज़र और सामान्य दोनों को स्वीकार करता है। यदि throws-क्लोज़र पास किया जाता है, तो mapValues कॉल को try की आवश्यकता होती है; यदि सामान्य है, तो try की आवश्यकता नहीं है। यह rethrows को Swift मानक लाइब्रेरी में map, filter, reduce जैसे उच्च-क्रम फ़ंक्शन के लिए आदर्श बनाता है। Apple की अनुशंसा: उन API के लिए rethrows का उपयोग करें जो throws-क्लोज़र स्वीकार करते हैं और एरर का एकमात्र स्रोत वह क्लोज़र है। यदि फ़ंक्शन अपनी स्वयं की एरर थ्रो कर सकता है, तो throws का उपयोग करें।

Checked बनाम unchecked अपवाद

Swift throws checked अपवादों (Java की तरह) के करीब है — थ्रो की गई एरर सिग्नेचर में घोषित की जाती हैं। Kotlin और Dart unchecked अपवादों का उपयोग करते हैं — सिग्नेचर में throws की आवश्यकता नहीं है। अंतर मौलिक है: checked डेवलपर को एरर संभालने के लिए मजबूर करता है (सुरक्षित लेकिन अधिक वर्बोज़), unchecked स्वतंत्रता देता है लेकिन एरर को संभालना भूलने का जोखिम बढ़ाता है। Swift ने throws के लिए checked चुना, Kotlin ने सभी अपवादों के लिए unchecked। दोनों दृष्टिकोणों के लाभ हैं: Swift भाषा स्तर पर अधिक विश्वसनीय है, Kotlin अधिक संक्षिप्त और कार्यात्मक परिवर्तन श्रृंखलाओं में सुविधाजनक है।

कस्टम एरर प्रकार

मोबाइल एप्लिकेशन में संरचित एरर हैंडलिंग के लिए, बेस Exception या Error का उपयोग करने के बजाय कस्टम एरर प्रकार बनाने की अनुशंसा की जाती है। Swift में इसके लिए Error प्रोटोकॉल के साथ enum का उपयोग किया जाता है; Kotlin में Throwable (या Exception) से विरासत प्राप्त करने वाली sealed class; Dart में Exception से विरासत प्राप्त करने वाली class। कस्टम प्रकार एरर को श्रेणियों में समूहित करने और संबद्ध डेटा पास करने की अनुमति देते हैं।

भाषाएरर प्रकारविशेषता
Swiftenum: Error { ... }संबद्ध मान, catch में exhaustive switch
Kotlinsealed class : Throwable()फ़ील्ड वाली एरर के लिए Data class, when-अभिव्यक्ति
Dartclass implements ExceptionMessage फ़ील्ड, catch में on-क्लॉज़
Javaclass extends ExceptionChecked बनाम unchecked, सिग्नेचर में अनिवार्य throws

कस्टम एरर डिज़ाइन करते समय, नियम का पालन करें: एक एरर — एक परिदृश्य। विभिन्न कारणों को String message फ़्लैग वाले एक प्रकार में संयोजित न करें — प्रत्येक परिदृश्य के लिए अलग-अलग केस/उपवर्ग बनाएं। इससे कॉल करने वाला पक्ष स्ट्रिंग तुलना के बजाय पैटर्न मैचिंग (when/switch) के माध्यम से प्रत्येक मामले को संभाल सकेगा। Swift में यह exhaustive checking प्रदान करता है — कंपाइलर चेतावनी देगा यदि NetworkError enum का कोई केस संभाला नहीं गया है।

Kotlin में कस्टम एरर का उदाहरण

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 (Kotlin में मानक अपवाद प्रकार) से विरासत प्राप्त करता है। प्रत्येक उपवर्ग अपने स्वयं के फ़ील्ड वाली data class है: Timeout में मिलीसेकंड में टाइमआउट अवधि होती है, HttpError में कोड और प्रतिक्रिया निकाय होता है, NoConnection में मूल IOException होता है। यह डिज़ाइन when के माध्यम से व्यापक मिलान के साथ प्रत्येक एरर को संभालने की अनुमति देता है (जब आप एक नया उपवर्ग जोड़ते हैं, तो कंपाइलर सभी when-अभिव्यक्तियों को अपडेट करने के लिए बाध्य करेगा)।

Swift में Try, try? और try!

Swift throws-फ़ंक्शन कॉल करने के तीन तरीके प्रदान करता है, प्रत्येक अपने स्वयं के सुरक्षा अनुबंध के साथ। try मानक तरीका है: इसे do-catch की आवश्यकता है या throws-फ़ंक्शन के अंदर होना चाहिए। try? एरर को nil में बदल देता है — परिणाम वैकल्पिक हो जाता है, एरर पर nil लौटाता है, प्रकार T से T? में बदल जाता है। try! — बिना हैंडलिंग के अनिवार्य निष्पादन: यदि कोई एरर थ्रो होता है, तो एप्लिकेशन क्रैश हो जाता है। try! का उपयोग केवल तभी करें जब आप पूरी तरह से आश्वस्त हों कि एरर असंभव है (उदाहरण के लिए, स्पष्ट रूप से मान्य डेटा)।

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

// try? — वैकल्पिक परिणाम
let data = try? Data(contentsOf: URL(fileURLWithPath: configPath))
let json = try? JSONSerialization.jsonObject(with: data ?? Data())

// try! — गारंटीकृत सफलता (केवल जब आश्वस्त हों)
let decoder = JSONDecoder()
let defaultConfig = try! decoder.decode(
    Config.self,
    from: Config.defaultJSON
)

// try — मानक हैंडलिंग
do {
    let user = try fetchUser()
    showUser(user)
} catch let error as NetworkError {
    showRetryAlert(error.message)
}

उदाहरण में, try! का उपयोग ऐप बंडल में एम्बेडेड स्पष्ट रूप से मान्य JSON के लिए किया जाता है — सही रिलीज़ के साथ डिकोडिंग एरर असंभव है। try? का उपयोग कॉन्फ़िगरेशन फ़ाइल पढ़ने के लिए किया जाता है — यदि फ़ाइल गायब या दूषित है, तो एप्लिकेशन क्रैश होने के बजाय डिफ़ॉल्ट मान का उपयोग करता है। try का do-catch में उपयोग नेटवर्क अनुरोधों के लिए किया जाता है जहाँ एरर अपेक्षित है और उपयोगकर्ता प्रतिक्रिया की आवश्यकता है। अनुशंसा: प्रोडक्शन कोड में try! से बचें — केवल बिल्ड समय पर सत्यापित निरंतर डेटा के लिए इसका उपयोग करें।

अक्सर पूछे जाने वाले प्रश्न

Swift में throw और throws में क्या अंतर है?

Throw एक ऑपरेटर है जो प्रोग्राम निष्पादन के दौरान एक एरर थ्रो करता है, प्रवाह को बाधित करता है। Throws एक फ़ंक्शन सिग्नेचर संशोधक है जो घोषित करता है कि फ़ंक्शन एक एरर थ्रो कर सकता है। बिना throws वाला फ़ंक्शन throw का उपयोग नहीं कर सकता। Throws एक कंपाइल-टाइम अनुबंध है, throw एक रनटाइम क्रिया है।

Kotlin में throws क्यों नहीं है?

Kotlin unchecked अपवादों के दर्शन का पालन करता है: सभी अपवाद वाक्यात्मक बाध्यता के बिना अनियंत्रित रह सकते हैं। Kotlin डेवलपर मानते हैं कि Java में throws अत्यधिक try-catch ब्लॉक और खाली catch के माध्यम से checked अपवादों को अनदेखा करने की ओर ले जाता है। Kotlin का Nothing प्रकार throw को अभिव्यक्ति के रूप में उपयोग करने की अनुमति देता है, throws को अधिक लचीले दृष्टिकोण से बदलता है।

Swift में try! का उपयोग कब करें?

try! केवल तभी स्वीकार्य है जब आप पूरी तरह से आश्वस्त हों कि एरर असंभव है: बंडल से स्पष्ट रूप से मान्य JSON, निरंतर डेटा, सही URL स्कीम। प्रोडक्शन कोड में, try! एक अपवाद है, नियम नहीं। try? फ़ॉलबैक मान वाले वैकल्पिक परिदृश्यों के लिए बेहतर है, अनिवार्य एरर हैंडलिंग के लिए try do-catch के साथ।

Swift में rethrows क्या है?

Rethrows उन फ़ंक्शन के लिए एक संशोधक है जो throws-क्लोज़र स्वीकार करते हैं। rethrows वाला फ़ंक्शन केवल तभी एरर थ्रो करता है जब पास किए गए क्लोज़र ने एक थ्रो किया। यह उच्च-क्रम फ़ंक्शन (map, filter) को कॉल करने वाले पक्ष पर try को मजबूर किए बिना throws और non-throws दोनों क्लोज़र के साथ काम करने की अनुमति देता है।

क्या catch ब्लॉक के अंदर एरर थ्रो कर सकते हैं?

हाँ, catch के अंदर आप एरर को एक अलग प्रकार में लपेटकर या संदर्भ जोड़कर स्टैक में ऊपर प्रसारित करने के लिए throw का उपयोग कर सकते हैं। इसे error chaining या rethrow कहा जाता है। Swift में, catch के अंदर एक और throw पर्याप्त है; Kotlin में, catch ब्लॉक के अंदर throw। finally ब्लॉक नियंत्रण को आगे भेजने से पहले निष्पादित होता है।

सारांश

  • Throw — एक अपवाद थ्रो ऑपरेटर जो वर्तमान प्रवाह को बाधित करता है और एरर ऑब्जेक्ट को स्टैक में ऊपर भेजता है
  • Throws — फ़ंक्शन सिग्नेचर में एरर की संभावना के बारे में कंपाइल-टाइम घोषणा, Swift में अनिवार्य, Kotlin में अनुपस्थित
  • Swift में throw enum: Error स्वीकार करता है, फ़ंक्शन को throws से चिह्नित किया जाता है, try / try? / try! के माध्यम से कॉल किया जाता है
  • Kotlin में throw Nothing प्रकार की अभिव्यक्ति है, जो when, एल्विस ऑपरेटर और असाइनमेंट में उपयोग की अनुमति देता है
  • Swift में Rethrows उच्च-क्रम फ़ंक्शन को केवल पास किए गए क्लोज़र से एरर प्रसारित करने की अनुमति देता है
  • कस्टम एरर विस्तृत जानकारी के लिए संबद्ध मानों के साथ enum (Swift) या sealed class (Kotlin) के माध्यम से बनाए जाते हैं
  • पैटर्न मैचिंग के माध्यम से सुविधाजनक हैंडलिंग के लिए "एक केस — एक परिदृश्य" सिद्धांत पर एरर प्रकार डिज़ाइन करें

हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे

IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।

परियोजना पर चर्चा करें

यह भी पढ़ें