companion object Kotlin भाषा का एक तंत्र है जो क्लास के स्थैतिक सदस्यों को घोषित करने के लिए Java के static कीवर्ड को बदलता है। Kotlin में अंतर्निहित static नहीं है — इसके बजाय, क्लास के अंदर companion मॉडिफ़ायर के साथ object घोषणा का उपयोग किया जाता है। JetBrains, 2025 के अनुसार, companion object क्लास नाम के माध्यम से विधियों और गुणों को कॉल करने की अनुमति देता है, जो Java इकोसिस्टम में स्थैतिक सदस्यों का पूर्ण समकक्ष बनाता है।
मुख्य बातें
companion object Kotlin में object declaration का एक विशेष प्रकार है जिसे companion कीवर्ड से चिह्नित किया जाता है। यह उन सदस्यों को घोषित करने की अनुमति देता है जो क्लास के इंस्टेंस के बजाय क्लास से संबंधित होते हैं — यानी Java शब्दों में स्थैतिक सदस्य। Java के विपरीत, जहाँ static व्यक्तिगत फ़ील्ड और विधियों के लिए एक मॉडिफ़ायर है, Kotlin में स्थैतिक सदस्यों को एक ही साथी ऑब्जेक्ट के अंदर समूहित किया जाता है।
Kotlin में कोई भी क्लास बिल्कुल एक companion object रख सकता है। इस ऑब्जेक्ट के सदस्य इंस्टेंस बनाए बिना क्लास नाम के माध्यम से सुलभ हैं: MyClass.method(). बाइटकोड के संदर्भ में, companion object एक अलग आंतरिक क्लास में संकलित होता है, और @JvmStatic एनोटेशन का उपयोग करने पर इसकी विधियाँ बाहरी क्लास की स्थैतिक विधियाँ बन जाती हैं।
Google I/O 2024 के अनुसार, companion object Kotlin में लिखे आधुनिक Android अनुप्रयोगों में फ़ैक्टरी विधियों, स्थिरांकों और सहायक कार्यों के लिए मुख्य पैटर्न बन गया है। डेवलपर इसे पैकेज-स्तरीय कार्यों वाली उपयोगिता क्लासों के बजाय चुनते हैं क्योंकि companion object स्वामी क्लास के साथ तार्किक संबंध बनाए रखता है।
स्थैतिक संदर्भ को समूहित करने के लिए companion object का उपयोग करें — स्थिरांक, फ़ैक्टरी, सहायक विधियाँ जो तार्किक रूप से क्लास से संबंधित हैं लेकिन इंस्टेंस की आवश्यकता नहीं है।
companion object का मूल सिंटैक्स सरल है: companion कीवर्ड क्लास के अंदर object घोषणा से पहले रखा जाता है। यदि कोई नाम निर्दिष्ट नहीं किया जाता है, तो ऑब्जेक्ट को Companion नाम मिलता है, जिसे स्पष्ट या अप्रत्यक्ष रूप से एक्सेस किया जा सकता है।
class User {
companion object {
const val TABLE_NAME = "users"
fun create(name: String): User {
return User(name)
}
}
val name: String
constructor(name: String) { this.name = name }
}
// Access via class name
val table = User.TABLE_NAME
val user = User.create("Alice")
उपरोक्त उदाहरण में, TABLE_NAME और create() User.TABLE_NAME और User.create() के माध्यम से सुलभ हैं। आदिम स्थिरांकों के लिए const मॉडिफ़ायर पर ध्यान दें — यह संकलन समय पर मान इनलाइनिंग की गारंटी देता है, जो आदिम और String के लिए Java static final के समान है।
यदि companion object का कोई नाम नहीं है, तो इसे स्वचालित नाम Companion: User.Companion.TABLE_NAME के माध्यम से एक्सेस किया जा सकता है। व्यवहार में यह शायद ही कभी आवश्यक होता है, लेकिन Java कोड से कॉल करते समय या रिफ्लेक्शन का उपयोग करते समय उपयोगी है।
// Both calls are equivalent
User.create("Bob")
User.Companion.create("Bob")
// Getting reference to companion object
val companion: User.Companion = User
companion object का एक नाम हो सकता है, जो कोड पठनीयता में सुधार करता है और इसे एक सार्थक नाम से एक्सेस करने की अनुमति देता है। Factory फ़ैक्टरी के रूप में उपयोग किए जाने वाले companion object के लिए सबसे आम नाम है।
class HttpResponse {
companion object Factory {
fun ok(body: String): HttpResponse = HttpResponse(200, body)
fun notFound(): HttpResponse = HttpResponse(404, "Not Found")
fun serverError(): HttpResponse = HttpResponse(500, "Internal Error")
}
}
// Access via Factory name
val response = HttpResponse.Factory.ok("data")
नामांकित companion object स्थैतिक सदस्यों के उद्देश्य को दस्तावेज़ित करने में मदद करता है। रीफ़ैक्टरिंग में, नाम कोड को स्व-दस्तावेज़ीकृत बनाता है — डेवलपर तुरंत देखता है कि Factory HttpResponse के इंस्टेंस बनाता है।
एक क्लास में केवल एक companion object हो सकता है। यह Java से एक मूलभूत अंतर है, जहाँ आप बिना समूहीकरण के किसी भी संख्या में स्थैतिक फ़ील्ड और विधियाँ घोषित कर सकते हैं। यदि स्थैतिक सदस्यों के कई तार्किक समूहों की आवश्यकता है, तो companion के बिना नेस्टेड object घोषणाओं का उपयोग करें।
आधिकारिक Kotlin दस्तावेज़ीकरण (Kotlin Docs, 2025) के अनुसार, एक companion object की सीमा भाषा डिज़ाइन से प्रेरित है: स्थैतिक सदस्यों को क्लास के साथ मजबूती से जुड़ा होना चाहिए, और एक साथी ऑब्जेक्ट इस संबंध के लिए एक स्पष्ट सीमा प्रदान करता है। यदि बहुत अधिक स्थैतिक सदस्य हैं, तो यह क्लास को रीफ़ैक्टर करने का संकेत है।
Kotlin में, इंटरफ़ेस भी companion object रख सकते हैं। यह सीधे इंटरफ़ेस के अंदर स्थैतिक विधियों और स्थिरांकों को परिभाषित करने की अनुमति देता है, जो Java में संभव नहीं है। यह दृष्टिकोण अक्सर इंटरफ़ेस से संबंधित स्थिरांक या फ़ैक्टरी विधियों की घोषणा के लिए उपयोग किया जाता है।
interface ApiService {
companion object {
const val BASE_URL = "https://api.example.com"
const val TIMEOUT_MS = 5000
fun create(client: OkHttpClient): ApiService =
Retrofit.Builder()
.baseUrl(BASE_URL)
.client(client)
.build()
.create(ApiService::class.java)
}
}
इस उदाहरण में, BASE_URL, TIMEOUT_MS और create() ApiService इंटरफ़ेस से संबंधित हैं, न कि इसके कार्यान्वयन से। यह सुविधाजनक है: सभी स्थिरांक और API सेवा इंस्टेंस बनाने का फ़ैक्टरी तर्क एक ही स्थान पर — इंटरफ़ेस के अंदर ही स्थित हैं।
इंटरफ़ेस कार्यान्वयन companion object के सदस्यों को इनहेरिट नहीं करते — वे केवल इंटरफ़ेस नाम: ApiService.BASE_URL के माध्यम से कॉल किए जाते हैं।
Java कोड से companion object विधियों को कॉल करते समय, डिफ़ॉल्ट रूप से वे बाहरी क्लास की स्थैतिक विधियों के बजाय नेस्टेड Companion क्लास की विधियों के रूप में सुलभ होती हैं। उन्हें Java के लिए वास्तविक स्थैतिक विधियों और फ़ील्ड के रूप में निर्यात करने के लिए, विधियों के लिए @JvmStatic और फ़ील्ड के लिए @JvmField एनोटेशन का उपयोग करें।
| एनोटेशन | अनुप्रयोग | Java में परिणाम |
|---|---|---|
| @JvmStatic | Companion object विधियाँ | स्थैतिक विधि: ClassName.method() |
| @JvmField | Companion object फ़ील्ड | स्थैतिक फ़ील्ड: ClassName.field |
| const | आदिम और String | इनलाइन स्थिरांक: कंपाइलर मान प्रतिस्थापित करता है |
| बिना एनोटेशन | डिफ़ॉल्ट रूप से विधियाँ/फ़ील्ड | Companion.method() / Companion.field |
class MathUtils {
companion object {
const val PI = 3.14159
@JvmStatic
fun square(x: Int): Int = x * x
@JvmField
val TAG: String = "MathUtils"
}
}
// Called in Java as MathUtils.square(5), MathUtils.TAG
सभी सार्वजनिक companion object विधियों के लिए @JvmStatic का उपयोग करने की अनुशंसा की जाती है जो Java कोड से सुलभ होनी चाहिए। const केवल आदिम प्रकारों और String पर लागू होता है — अन्य प्रकारों के लिए @JvmField का उपयोग करें।
वास्तविक परियोजनाओं में, companion object कई मानक परिदृश्यों के लिए उपयोग किया जाता है। फ़ैक्टरी विधियाँ सबसे आम पैटर्न हैं: विभिन्न हस्ताक्षरों वाले कई कंस्ट्रक्टरों के बजाय, companion object में नामांकित फ़ैक्टरी विधियों का उपयोग किया जाता है।
sealed class NetworkResult<out T> {
data class Success<out T>(val data: T) : NetworkResult<T>()
data class Error(val message: String) : NetworkResult<Nothing>()
companion object {
fun loading<T>(): NetworkResult<T> =
Loading()
}
}
private class Loading<T> : NetworkResult<T>()
NetworkResult में companion object एक फ़ैक्टरी विधि loading() प्रदान करता है जो सही generic प्रकार के साथ Loading इंस्टेंस बनाता है। इस विधि के बिना, आपको सीधे Loading() के माध्यम से इंस्टेंस बनाना होगा, जो आंतरिक कार्यान्वयन को उजागर करता है।
companion object का उपयोग अक्सर क्लास-विशिष्ट स्थिरांक संग्रहीत करने के लिए किया जाता है। const val के साथ घोषित स्थिरांक संकलन समय पर इनलाइन होते हैं, जो रनटाइम पर शून्य ओवरहेड प्रदान करते हैं।
class UserRepository {
companion object {
private const val TAG = "UserRepository"
private const val CACHE_SIZE = 100
private const val DEFAULT_PAGE_SIZE = 20
}
}
अक्सर पूछे जाने वाले प्रश्न
सामान्य object एक पूर्ण सिंगलटन है जो क्लास से स्वतंत्र रूप से मौजूद होता है। companion object क्लास के अंदर एक object है जिसके सदस्य बाहरी क्लास नाम के माध्यम से कॉल किए जाते हैं। बाइटकोड में, companion object एक स्थैतिक नेस्टेड क्लास बन जाता है, जबकि सामान्य object एक स्वायत्त सिंगलटन क्लास बन जाता है।
नहीं, companion object उपवर्गों द्वारा इनहेरिट नहीं किया जाता है। यदि क्लास B, क्लास A का विस्तार करता है, तो B.method() क्लास A के companion object से विधि को कॉल नहीं करेगा — आपको A.method() के माध्यम से कॉल करना होगा। यह Java में स्थैतिक विधियों के व्यवहार से मेल खाता है।
डिफ़ॉल्ट रूप से — ClassName.Companion.method() के माध्यम से। इसे स्थैतिक विधि के रूप में कॉल करने के लिए, companion object विधि में @JvmStatic जोड़ें। फ़ील्ड के लिए, @JvmField का उपयोग करें या उन्हें आदिम के लिए const val के साथ घोषित करें।
Kotlin डेवलपर्स ने वस्तुओं के साथ एकसमान काम करने के लिए static को छोड़कर companion object को अपनाने का निर्णय लिया। Java में static OOP सिद्धांतों का उल्लंघन करता है क्योंकि स्थैतिक विधियाँ किसी इंस्टेंस से बंधी नहीं होती हैं। companion object प्रथम श्रेणी की वस्तु है जिसे पास किया जा सकता है, एक्सटेंशन फ़ंक्शन के साथ बढ़ाया जा सकता है और इंटरफ़ेस लागू किया जा सकता है।
आदिम और String के लिए const val का उपयोग करते समय — शून्य ओवरहेड, मान बाइटकोड में इनलाइन होता है। विधियों के लिए, कोई ओवरहेड नहीं है जब तक कि विधि inline न हो। अधिकांश मामलों में, companion object प्रदर्शन पर कोई मापने योग्य प्रभाव नहीं बनाता है। केवल Java से कॉल किए जाने वाले सार्वजनिक API के लिए @JvmStatic का उपयोग करें।
सारांश
हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे
IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।
यह भी पढ़ें