2013-04-28 10 views
6

यहाँ एक उदाहरण है:int.class.isInstance (ऑब्जेक्ट) एक विरोधाभास है?

public boolean check(Class<?> clazz, Object o) 
{ 
    return clazz.isInstance(o); 
} 

check(int.class, 7); // returns false 

isInstance के बाद से एक Object स्वीकार करता है, यह int साथ काम नहीं करेंगे, क्योंकि int एक आदिम प्रकार है और Integer को autoboxed हो जाता है। क्या सामान्य जेनेरिक चेक विधि लिखना संभव है? या मुझे यह सुनिश्चित करना चाहिए कि क्लैज Class<? extends Object> प्रकार का है?

+4

'int',' प्रकार' या यहां तक ​​कि 'isintance' जैसे बहुत सार्थक टैग का उपयोग करने के बजाय, आपको उस भाषा के साथ प्रश्न टैग करना चाहिए जिसका आप उपयोग कर रहे हैं। इससे अधिक दर्शक आकर्षित होंगे, और इसलिए आपको एक संतोषजनक उत्तर प्राप्त करने का मौका बढ़ जाएगा। –

+1

श्रीमान, मैं पूरी तरह से भूल गया। ... मुझे लगता है कि जावा मेरे लिए प्राकृतिक हो गया है: डी – mike

+2

क्या आपने [यह जवाब] पढ़ा था (http://stackoverflow.com/a/7083456/516433) अभी तक? – Lucas

उत्तर

6

सभी Class ऑब्जेक्ट्स कक्षा/संदर्भ प्रकारों का प्रतिनिधित्व नहीं करते हैं; Class ऑब्जेक्ट्स भी हैं जो प्राचीन प्रकार का प्रतिनिधित्व करते हैं। यह उपयोगी है क्योंकि फ़ील्ड और विधियों के साथ प्रतिबिंब का उपयोग करने में, आपको अक्सर अपने प्रकार को निर्दिष्ट करने की आवश्यकता होती है, और यह एक आदिम प्रकार हो सकता है। तो Class का उपयोग ऐसे सभी पूर्व-जेनेरिक प्रकारों का प्रतिनिधित्व करने के लिए किया जाता है।

हालांकि, Class कक्षा के कई तरीकों से प्राचीन प्रकार के लिए कोई अर्थ नहीं है। उदाहरण के लिए, किसी ऑब्जेक्ट के लिए instanceof int होना असंभव है। इसलिए, समान .isInstance() विधि हमेशा false वापस आ जाएगी। चूंकि उस विधि का पैरामीटर Object टाइप है, इसलिए मूलभूत प्रकार के होने के लिए आप जो भी पास करते हैं, उसके लिए भाषा बिंदु से यह असंभव है।

ज़रूर, जावा में 5 + जब आप प्रकार Object की एक पैरामीटर के लिए एक आदिम गुजरती हैं, यह autoboxing से होकर गुजरती है, लेकिन तथ्य यह है कि यह autoboxing लिया मतलब है कि क्या पारित किया गया था वास्तव में एक वस्तु के लिए एक संदर्भ है। संदर्भ प्रकार और आदिम प्रकार अलग हैं। एक पैरामीटर या तो एक संदर्भ प्रकार या आदिम प्रकार है। इस प्रकार आप एक ऐसी विधि नहीं लिख सकते जो "संदर्भ या आदिम" ले सके।

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

हालांकि, यह मानते हुए कि यह ऑटोबॉक्साइड था, आप जानते हैं कि इसे किस प्रकार जाना चाहिए था। यदि आप int की अपेक्षा कर रहे हैं, और यह ऑटोबॉक्स्ड है और आपकी विधि से गुजरता है, तो यह Integer का उदाहरण होना चाहिए।इस प्रकार, आप क्या कर सकते हैं, जब clazz एक प्राचीन प्रकार का प्रतिनिधित्व करता है, इसके बजाय इसकी रैपर कक्षा पर जांच करें। इस प्रकार, जब यह देखता है कि clazzint.class है, तो इसे Integer.class के साथ प्रतिस्थापित करें, और उसके बाद चेक करें। ध्यान दें कि इस तरह से अभी भी यह नहीं बताया गया है कि o पैरामीटर के रूप में क्या पारित किया गया था या नहीं।

+0

मैंने कुछ शोध किया, ऐसा लगता है कि एक प्राचीन प्रकार के रैपर वर्ग, या एक रैपर वर्ग के प्रकार क्षेत्र प्राप्त करने के लिए एक सामान्य तरीका पाने के लिए कोई सामान्य विधि नहीं है। मुझे लगता है कि मुझे एक नक्शा हार्ड कोड करना है और उस पर एक लुकअप करना है। – mike

+1

@ माइक यदि आप गुवा का उपयोग करते हैं, तो ['Primitives'] (http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/primitives/Primitives.html) कक्षा हैंडल वे पहले से ही मामलों का उपयोग करते हैं। –

+0

धन्यवाद लेकिन, अमरूद विधियां भी एक हार्ड कोडित मानचित्र पर भरोसा करती हैं। वैसे भी, महान जवाब और टिप्पणियां यहां, मैंने बहुत कुछ सीखा! – mike

2

जावा में int कक्षा नहीं है। इसकी Integer कक्षा। 7 को Integer.valueOf(7) में परिवर्तित किया गया है, और int.class को जेएलएस के अनुसार Integer.class में परिवर्तित कर दिया जाएगा।

तो p एक आदिम प्रकार का नाम है, B मुक्केबाजी रूपांतरण के बाद प्रकार p के अभिव्यक्ति के प्रकार के हो सकते हैं। फिर p.classClass<B> है।

Integer एक वर्ग वस्तु है, जबकि int आदिम प्रकार है। इसलिए, Class जैसे isInstance, isAssignableFrom आदि के अधिकांश तरीके ऑब्जेक्ट्स पर संचालित होते हैं int.class के संदर्भ में अमान्य हैं, इसलिए आप उस विरोधाभास को देखते हैं।

check(Integer.class, 7); 

अपेक्षित परिणाम देना चाहिए।

+0

मैं जेनेरिक सेटर के संदर्भ में चेक विधि का एक रूप उपयोग करता हूं, जहां मैं सेटर के पैरामीटर प्रकार के साथ सेट करने और इसकी तुलना करने के लिए विशेषता से प्रकार की जानकारी निकालता हूं। इसलिए मुझे उन विशेषताओं के लिए आदिम प्रकारों को प्रतिबंधित करना चाहिए जिन्हें मैं सेट करना चाहता हूं? – mike

+0

इस सामान्य सेटटर के लिए कोड दिखाने के लिए यह उपयोगी होगा। यदि यह ' शून्य सेट कुछ (टी द टिंगिंग) 'जैसा है, तो आप सीधे प्राइमेटिव्स का उपयोग करने में सक्षम नहीं होंगे - वे हमेशा ऑटोबॉक्साइड होंगे, क्योंकि जेनेरिक प्रकार केवल ऑब्जेक्ट्स, कभी प्राइमेटिव नहीं हो सकते हैं। – BeeOnRope

+0

आप एसओ http://stackoverflow.com/questions/16225623/how-to-avoid-getters-setters-in-classes-with-many-instance-variables – mike

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