2015-11-12 4 views
5

प्रस्तावना:मैं जेनरिक को समझते हैं और कैसे वे कक्षा स्तर (उदाहरण के class MyClass<T>) पर घोषित कर रहे हैं लेकिन मैं इसे एक स्थिर विधि के स्तर पर घोषित कभी नहीं देखा है, और किसी भी स्पष्ट बाइंडिंग के बिना (जैसे class MySubclass<String> extends MyClass)।एक सामान्य विधि क्या है और <T> इस मामले में बाध्य कैसे है?

मुझे इस कोड स्निपेट को एक ऐप में मिला है जिस पर मैं काम कर रहा हूं (मैंने यह हिस्सा नहीं लिखा था)। मैंने इस तरह से घोषित एक विधि कभी नहीं देखी है। <T> कक्षा में कहीं और परिभाषित नहीं है। Intent.getExtras().get() एक Object देता है जो वास्तव में String, Boolean ... आदि हो सकता है।

private static <T> T getItemExtra(final Intent intent, final String extraName) { 
    T item = null; 

    if(intent != null && intent.getExtras() != null) { 
     item = (T) intent.getExtras().get(extraName); 
    } 

    return item; 
} 

नमूना उपयोग:

String s1 = getItemExtra(someIntent, "some_string_extra"); 
Uri u1 = getItemExtra(someIntent, "some_uri_extra"); 

JVM कैसे जान लेता है कि किस प्रकार <T> के लिए उपयोग करने के लिए? (हाँ यह विधि संकलित और सफलतापूर्वक निष्पादित)।

+3

दूसरे प्रश्न का दूरस्थ रूप से डुप्लिकेट नहीं है। –

+0

@ नीलिश मैं जेनेरिक वर्गों के बारे में पूछ रहा हूं, सामान्य वर्ग नहीं। मैंने इसे प्रतिबिंबित करने के लिए प्रश्न अपडेट किया है। –

+0

@ OliverGondža हाँ मुझे यह स्वीकार करना होगा कि यह एक डुप्लिकेट है। –

उत्तर

1

जावा में generic method के रूप में जाना जाता है। टी एक प्रकार का प्रतिनिधित्व करता है, जिसे आप सामान्य रूप से निर्दिष्ट करेंगे। संकलक तब टी के किसी भी उदाहरण को उस प्रकार से बदल देगा जिस प्रकार आपने इसे बदल दिया था। यदि आप नहीं करते हैं, तो संकलक उपलब्ध जानकारी से सही प्रकार का अनुमान लगाने का प्रयास करेगा।

आपको गहराई से स्पष्टीकरण में जावा Generics ट्यूटोरियल के माध्यम से देखना चाहिए।

1

T एक प्रकार इंटरफ़ेस के रूप में जाना जाता है। इस उदाहरण में, रिटर्न टाइप एक प्रकार का इंटरफ़ेस है, इसलिए बस यह कहकर कि getItemExtra(...)String या Uri लौटाएगा यह संकलक के लिए पर्याप्त है कि यह विधि उस ऑब्जेक्ट को वापस कर देगी। ऐसा कहा जा रहा है कि यह इंटरफेस टाइप करने के लिए पेश किया जाने वाला सबसे अच्छा उदाहरण नहीं है, इसलिए यहां एक आसान उदाहरण है।

ArrayList, एक प्रकार इंटरफ़ेस का उपयोग कर को छोड़कर आप ArrayList कह रहे हैं क्या ऑब्जेक्ट प्रकार यह शामिल होंगे कार्यान्वित किया जाता है T के बजाय वे E उपयोग कर रहे हैं, जो ठीक है क्योंकि चरित्र इतने लंबे समय के रूप में आप कि एक ही चरित्र में उपयोग मनमाना है सिवाय आपका कार्यान्वयन

public class ArrayList<E> extends AbstractList<E> 
     implements List<E>, RandomAccess, Cloneable, java.io.Serializable 
{ 

तो अगर आप ArrayList<String> घोषित संकलक संकलन समय पर String साथ E बदल देगा:

यहाँ वास्तविक implementation से कोई प्रासंगिक टुकड़ा है। ArrayList<YourCustomObject> के लिए वही जाता है, यह E को YourCustomObject के साथ कार्यान्वयन के दौरान प्रतिस्थापित करेगा।

+0

मेरा प्रश्न सामान्य तरीकों के बारे में जेनेरिक तरीकों के बारे में है। –

+0

यह वही बात है, जिसे आप कन्स्ट्रक्टर में निर्दिष्ट करते हैं, जिसे आप विधि को कॉल करते समय निर्दिष्ट करते हैं। – CodyEngel

3

JVM कैसे जानता है कि <T> के लिए किस प्रकार का उपयोग करना है?

मूल उत्तर यह नहीं है। जावा में, जेनेरिक प्रकारों का उपयोग कंपाइल समय पर प्रकार चेकर द्वारा किया जाता है, लेकिन जब प्रोग्राम वास्तव में चलता है तो प्रोग्राम से निकाल दिया जाता है। तो उदाहरण के लिए, T में में कास्ट वास्तव में रनटाइम पर कुछ भी नहीं करता है: यह प्रभावी रूप से Object पर कास्ट है, इस पर ध्यान दिए बिना कि कॉलर किस प्रकार T होने की अपेक्षा करता है।(यह एक सामान्य प्रकार से String की तरह एक सामान्य प्रकार से अलग है, जहां प्रोग्राम गलत तरीके से डालने का प्रयास करते समय तुरंत अपवाद के साथ विफल हो जाएगा।)

तथ्य यह है कि आप चेक के बिना T पर जा सकते हैं जावा की टाइप सिस्टम में लूपोल जो अजीब क्लास-कास्ट अपवाद का कारण बन सकता है। उदाहरण के लिए, अगर आप कहते हैं कि

String s = getItemExtra(...); 
s.toLowerCase(); 

लेकिन getItemExtra एक स्ट्रिंग वापस नहीं करता है, तो आप दूसरी पंक्ति पर एक अपवाद जो आपको बताएगा कि s एक स्ट्रिंग नहीं है, इसमें कोई डाली है, भले ही मिल जाएगा लाइन। इसी कारण से, जब जावा कंपाइलर T पर एक कास्ट देखता है तो यह एक अनचेक-कास्ट चेतावनी उत्पन्न करेगा, जो आपको बताएगा कि यह जांच नहीं सकता कि आपका टाइपकास्ट कानूनी था और आप इस तरह की समस्याओं में भाग ले सकते हैं।

+1

वास्तव में आपको पहली पंक्ति पर अपवाद मिलता है, क्योंकि पहली पंक्ति 'स्ट्रिंग एस = (स्ट्रिंग) प्राप्त होती है ITemExtra (...); '। –

संबंधित मुद्दे