जावा सरणी प्रतिबिंब: एराएरे बनाम इंस्टोफ़


जवाबों:


203

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

आम तौर पर, आप किसी विशेष प्रकार के डाउनकास्टिंग से पहले किसी ऑब्जेक्ट के प्रकार का परीक्षण करते हैं जिसे संकलन समय पर जाना जाता है। उदाहरण के लिए, शायद आपने कुछ कोड लिखे हैं जो a Integer[]या a के साथ काम कर सकते हैं 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 ...

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

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

दो विशेष मामले हैं: प्राथमिक संदर्भों के लिए अशक्त संदर्भ और संदर्भ।

एक अशक्त संदर्भ instanceofपरिणाम देगा false, जबकि isArrayफेंकता ए NullPointerException

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


7
हाँ, लेकिन इससे कितना फर्क पड़ता है? यह मेरे लिए एक माइक्रो-अनुकूलन की तरह लगता है।
माइकल मायर्स

2
@Dims आपको लगता है कि जोर देते हुए रहे हैं, तो obj instanceof int[]पैदावार falseजब आप एक आवंटित int[]करने के लिए obj, आप गलत कर रहे हैं।
इरिकसन

4
क्षमा करें, मेरा मतलब है कि यदि obj instanceof Object[]पैदावार । falseObject obj = new int[7]
मंद

3
सही, जावा में, आदिम डेटा प्रकार ऑब्जेक्ट नहीं हैं, और विस्तार नहीं करते हैं java.lang.Object, जिससे समझ में आता है। लेकिन instanceofअभी भी आदिम सरणियों के परीक्षण के लिए इस्तेमाल किया जा सकता है।
इरिकसन

4
-1: सामान्य तौर पर, के बाद से आदिम सरणियों हैं बुला सरणियों isArray()इस्तेमाल किया जाना चाहिए। बहुत में सामान्य नहीं केवल वस्तुओं की सरणियों होने के विशेष मामला है, instanceofएक उच्च प्रदर्शन विकल्प प्रदान करता है।
सैम हरवेल

33

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


8

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


4

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

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


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

4

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

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

इसे बदलना instanceof Object[]तय है।


इसका कोई अर्थ नहीं निकलता। isArrayकी एक विधि है Class, नहीं Type, तो निश्चित रूप से GenericArrayTypeImplउस विधि नहीं है। और getClassएक गैर वापस कभी नहीं कर सकते हैं Class Type, इसलिए आप (या Groovy ??) ने इसे पाने के लिए कुछ गलत किया होगा, जैसे कि यह मान लिया गया है कि हर Typeएक है Class
13

3

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

मैंने इस बारे में पहले दिसंबर में ब्लॉग किया था। http://blog.adamsbros.org/2010/12/08/java-array-reflection/


2

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


एर, ठीक है, "इंस्टोफ़" एक तरह का प्रतिबिंब (या, कम से कम, आत्मनिरीक्षण) है, लेकिन मुझे आपकी बात अच्छी लगी।
डेविड सिट्रोन

इसके अलावा, यह आमतौर पर धीमी है।
मैड फिजिसिस्ट

0

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

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.