टीएल; डीआर: किसके लिए reified
अच्छा है
fun <T> myGenericFun(c: Class<T>)
जैसे सामान्य कार्य के शरीर में myGenericFun
, आप प्रकार तक नहीं पहुँच सकते T
क्योंकि यह केवल संकलन समय पर उपलब्ध है, लेकिन रनटाइम पर मिटा दिया गया है। इसलिए, यदि आप फ़ंक्शन बॉडी में एक सामान्य वर्ग के रूप में जेनेरिक प्रकार का उपयोग करना चाहते हैं, तो आपको कक्षा में दिखाए गए पैरामीटर के रूप में स्पष्ट रूप से पास करने की आवश्यकता है myGenericFun
।
यदि आप किसी inline
फ़ंक्शन को किसी reified के साथ बनाते हैं T
, तो T
रनटाइम पर भी एक्सेस किया जा सकता है और इस प्रकार आपको Class<T>
इसके अतिरिक्त पास करने की आवश्यकता नहीं है । आप इसके साथ काम कर सकते हैं T
जैसे कि यह एक सामान्य वर्ग था, उदाहरण के लिए, आप जाँच सकते हैं कि क्या एक चर का एक उदाहरण है T
, जिसे आप आसानी से देख सकते हैं myVar is T
:।
प्रकार के inline
साथ इस तरह के एक समारोह इस प्रकार है:reified
T
inline fun <reified T> myGenericFun()
कैसे reified
काम करता है
आप केवल reified
एक inline
फ़ंक्शन के साथ संयोजन में उपयोग कर सकते हैं । ऐसा फ़ंक्शन कंपाइलर को फ़ंक्शन के बाइटकोड को हर उस स्थान पर कॉपी करता है जहां फ़ंक्शन का उपयोग किया जा रहा है (फ़ंक्शन "इनबिल्ड" हो रहा है)। जब आप एक इनलाइन फ़ंक्शन को रिफ़ाइंड प्रकार के साथ कॉल करते हैं, तो कंपाइलर वास्तविक प्रकार को एक तर्क के रूप में जानता है और उत्पन्न बाइटकोड को सीधे संबंधित वर्ग का उपयोग करने के लिए संशोधित करता है। इसलिए जैसे कॉल myVar is T
बन myVar is String
(यदि प्रकार तर्क थे String
बाईटकोड में और रनटाइम पर)।
उदाहरण
आइए एक उदाहरण देखें जो दिखाता है कि कितना उपयोगी reified
हो सकता है। हम String
कॉल के लिए एक एक्सटेंशन फ़ंक्शन बनाना चाहते हैं जो toKotlinObject
फ़ंक्शन के जेनेरिक प्रकार द्वारा निर्दिष्ट प्रकार के साथ एक JSON स्ट्रिंग को सादे कोटलिन ऑब्जेक्ट में बदलने की कोशिश करता है T
। हम इसके लिए उपयोग कर सकते हैं com.fasterxml.jackson.module.kotlin
और पहला तरीका निम्नलिखित है:
क) पहले प्रकार के बिना पुनरीक्षित प्रकार
fun <T> String.toKotlinObject(): T {
val mapper = jacksonObjectMapper()
//does not compile!
return mapper.readValue(this, T::class.java)
}
readValue
विधि एक प्रकार है कि यह पार्स करने के लिए चाहिए था लेता JsonObject
है। यदि हम Class
प्रकार के पैरामीटर को प्राप्त करने की कोशिश करते हैं T
, तो कंपाइलर शिकायत करता है: "T 'को रिवाइज्ड टाइप पैरामीटर के रूप में उपयोग नहीं किया जा सकता है। इसके बजाय एक वर्ग का उपयोग करें।"
बी) स्पष्ट Class
पैरामीटर के साथ समाधान
fun <T: Any> String.toKotlinObject(c: KClass<T>): T {
val mapper = jacksonObjectMapper()
return mapper.readValue(this, c.java)
}
समाधान के लिए, Class
की T
एक विधि पैरामीटर, जो तब के लिए एक तर्क के रूप में इस्तेमाल किया जा सकता है readValue
। यह काम करता है और जेनेरिक जावा कोड में एक सामान्य पैटर्न है। इसे इस प्रकार कहा जा सकता है:
data class MyJsonType(val name: String)
val json = """{"name":"example"}"""
json.toKotlinObject(MyJsonType::class)
ग) कोटलिन रास्ता: reified
प्रकार पैरामीटर के inline
साथ फ़ंक्शन का उपयोग करना फ़ंक्शन को अलग तरीके से लागू करना संभव बनाता है:reified
T
inline fun <reified T: Any> String.toKotlinObject(): T {
val mapper = jacksonObjectMapper()
return mapper.readValue(this, T::class.java)
}
लेने के लिए कोई ज़रूरत नहीं है Class
की T
इसके अतिरिक्त, T
इस्तेमाल किया जा सकता है कि यह एक साधारण वर्ग था। क्लाइंट के लिए कोड इस तरह दिखता है:
json.toKotlinObject<MyJsonType>()
महत्वपूर्ण नोट: जावा के साथ काम करना
reified
प्रकार के साथ एक इनलाइन फ़ंक्शन जावा कोड से कॉल करने योग्य नहीं है ।