2008-10-20 24 views

उत्तर

188

ज्यादातर मामलों में, आपको यह जांचने के लिए instanceof ऑपरेटर का उपयोग करना चाहिए कि कोई ऑब्जेक्ट एक सरणी है या नहीं।

आम तौर पर, आप किसी विशेष प्रकार के डाउनकास्टिंग से पहले ऑब्जेक्ट के प्रकार का परीक्षण करते हैं जो संकलन समय पर ज्ञात है। उदाहरण के लिए, शायद आपने कुछ कोड लिखा है जो Integer[] या int[] के साथ काम कर सकता है। आप instanceof के साथ अपने डाले रक्षा करने के लिए चाहते हैं:

if (obj instanceof Integer[]) { 
    Integer[] array = (Integer[]) obj; 
    /* Use the boxed array */ 
} else if (obj instanceof int[]) { 
    int[] array = (int[]) obj; 
    /* Use the primitive array */ 
} else ... 

JVM स्तर पर, instanceof ऑपरेटर एक विशिष्ट "instanceof" बाइट कोड है, जो सबसे JVM कार्यान्वयन में अनुकूलित है करने के लिए अनुवाद।

दुर्लभ मामलों में, आप अज्ञात प्रकारों के ऑब्जेक्ट ग्राफ़ को पार करने के लिए प्रतिबिंब का उपयोग कर रहे हैं। इस तरह के मामलों में, isArray() विधि उपयोगी हो सकती है क्योंकि आप संकलन समय पर घटक प्रकार नहीं जानते हैं; उदाहरण के लिए, आप कुछ प्रकार के क्रमिकरण तंत्र को कार्यान्वित कर सकते हैं और प्रकार के बावजूद सरणी के प्रत्येक घटक को उसी क्रमबद्ध विधि में पारित करने में सक्षम हो सकते हैं।

दो विशेष मामले हैं: शून्य संदर्भ और आदिम सरणी के संदर्भ।

एक अशक्त संदर्भ जबकि isArray एक NullPointerException फेंकता है, instanceoffalse परिणाम के लिए कारण होगा।

एक प्राचीन सरणी के लिए लागू, instanceoffalse उत्पन्न करता है जब तक दाएं हाथ के ऑपरेंड पर घटक प्रकार बिल्कुल घटक प्रकार से मेल नहीं खाता। इसके विपरीत, isArray() किसी भी घटक प्रकार के लिए true वापस करेगा।

+7

हाँ, लेकिन यह कितना अंतर बनाने जा रहा है? यह मेरे लिए सूक्ष्म अनुकूलन की तरह लगता है। –

+0

यह एप्लिकेशन पर निर्भर करता है, लेकिन मुझे आश्चर्य होगा कि आपके रास्ते से बाहर निकलने के लायक होने के लिए पर्याप्त अंतर है। लेकिन, चूंकि यह पारंपरिक दृष्टिकोण है, इसलिए अजीब, उप-इष्टतम प्रतिबिंब का उपयोग करने के लिए आपको कुछ विशेष कारण (आदिम सरणी के लिए समर्थन) होना चाहिए। – erickson

+6

'instanceof' अभिन्न प्रकार के सरणी के साथ काम नहीं करेगा। – Dims

31

बाद के मामले में, यदि obj शून्य है तो आपको NullPointerException नहीं मिलेगा लेकिन झूठा।

0

व्यवहार में कोई अंतर नहीं है जो मैं दोनों (स्पष्ट शून्य मामले के अलावा) के बीच पा सकता हूं। किस संस्करण के लिए पसंद है, मैं दूसरे के साथ जाना होगा। जावा में ऐसा करने का यह मानक तरीका है।

यदि यह आपके कोड के पाठकों को भ्रमित करता है (क्योंकि String[] instanceof Object[] सत्य है), तो कोड समीक्षाकर्ता इसके बारे में पूछने पर पहले अधिक स्पष्ट होना चाहेंगे।

2

यदि आपके पास कभी भी एक प्रतिबिंबित समाधान और गैर-परावर्तक समाधान के बीच कोई विकल्प है, तो कभी भी प्रतिबिंबित (कक्षा वस्तुओं को शामिल करना) चुनें। ऐसा नहीं है कि यह "गलत" या कुछ भी है, लेकिन प्रतिबिंब शामिल कुछ भी आम तौर पर कम स्पष्ट और कम स्पष्ट है।

+0

एर, ठीक है, "exampleof" एक तरह का प्रतिबिंब (या, कम से कम, आत्मनिरीक्षण) है, लेकिन मुझे आपकी बात मिलती है। –

+0

इसके अलावा, यह आमतौर पर धीमा है। –

8

हैं obj प्रकार int[] की है कहते हैं, तो वह एक सरणी Class होगा लेकिन Object[] का एक उदाहरण नहीं हो। तो आप obj के साथ क्या करना चाहते हैं। यदि आप इसे डालने जा रहे हैं, तो instanceof के साथ जाएं। यदि आप प्रतिबिंब का उपयोग करने जा रहे हैं, तो .getClass().isArray() का उपयोग करें।

4

getClass().isArray() आईबीएम की तुलना में सन जावा 5 या 6 जेआरई पर काफी धीमा है।

इतना है कि clazz.getName().charAt(0) == '[' का उपयोग सूर्य JVM पर तेज़ है।

+10

क्या आपके पास कोई आंकड़ा, केस स्टडी, या अन्य सबूत हैं जिनसे आप लिंक कर सकते हैं? –

3

जावा सरणी प्रतिबिंब उन मामलों के लिए है जहां आपके पास "exampleof" करने के लिए उपलब्ध कक्षा का उदाहरण नहीं है। उदाहरण के लिए, यदि आप किसी प्रकार का इंजेक्शन फ्रेमवर्क लिख रहे हैं, जो कि क्लास के नए उदाहरण में मूल्य इंजेक्ट करता है, जैसे कि जेपीए करता है, तो आपको isArray() कार्यक्षमता का उपयोग करने की आवश्यकता होती है।

मैंने दिसंबर में इस बारे में पहले ब्लॉग किया था।

MissingMethodException: 
No signature of sun.reflect.generics.reflectiveObjects.GenericArrayTypeImpl.isArray() ... 

instanceof Object[] इस तय करने के लिए बदल रहा है: http://blog.adamsbros.org/2010/12/08/java-array-reflection/

4

मैं हाल ही में उपयोग करना JDK 5 से JDK 6. करने के लिए एक ग्रूवी आवेदन isArray() JDK6 में विफल रहा है उन्नयन एक मुद्दा में भाग गया।

+0

यह कोई मतलब नहीं है। 'isArray'' वर्ग' का एक तरीका है, न कि 'टाइप', इसलिए निश्चित रूप से' जेनेरिकअरेय टाइप आईएमएलएल 'में वह विधि नहीं है। और 'getClass' कभी भी एक गैर-क्लास' प्रकार टाइप नहीं कर सकता है, इसलिए आप (या ग्रोवी ??) ने इसे प्राप्त करने के लिए कुछ गलत किया होगा, जैसे कि प्रत्येक' टाइप' 'वर्ग' है। – kaqqao

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