2016-12-13 18 views
9

द्वारा सरणी की जगह ले सकता:classloader कुछ भी

ClassLoader c = new ClassLoader() { 
    @Override 
    public Class<?> findClass(String name) { 
     return Object.class; 
    } 
}; 

Class<?> cc = c.loadClass(Object[][].class.getName()); 

System.out.println(cc.getName()); 

मैं प्रदर्शन टर्मिनल में java.lang.Object मिलता है, भले ही मैं कोड में [[Ljava.lang.Object द्वारा Object[][].class.getName() बदलें। समस्या यह है कि मैं कंसोल को [[Ljava.lang.Object दिखाने की उम्मीद कर रहा था।

वास्तव में, JVM specification में, मैं निम्नलिखित पढ़ सकते हैं:

एक सरणी वर्ग सीधे जावा आभासी मशीन (§5.3.3) द्वारा बनाई गई है, एक वर्ग लोडर द्वारा नहीं। हालांकि, डी के निर्णायक वर्ग लोडर सरणी वर्ग सी बनाने

Object[][] के बाद से एक सरणी वर्ग है की प्रक्रिया में प्रयोग किया जाता है, मैं मान लिया है कि मेरी findClass तर्क [[Ljava.lang.Object साथ लेकिन इसकी तत्व के साथ नहीं कहा जा होगा java.lang.Object टाइप करें।

इसके अलावा, अनुभाग "सरणी वर्ग बनाना" में, पुनरावर्ती एल्गोरिदम वास्तव में वर्णित है:

घटक प्रकार एक संदर्भ प्रकार, इस खंड (§5.3) के कलन विधि का उपयोग रिकर्सिवली लागू किया जाता है तो आदेश लोड करने के लिए और इस तरह बनाने सी

के घटक प्रकार

में वर्ग लोडर एल तो मेरी प्रश्न हैं:

  • मैं इस outp क्यों मिल रही है ut? क्या इसका मतलब यह है कि मुझे अपने क्लासलोडर के अंदर इस रिकर्सिव एल्गोरिदम को मैन्युअल रूप से शामिल करना है, बजाय JVM को मेरे लिए यह करने की बजाय? यदि इसका मतलब है, तो ऐसा करने का सबसे अच्छा तरीका क्या है?
  • क्या मैं पहले उद्धरण में "बनाए गए" को गलत व्याख्या कर रहा हूं? क्या इसका मतलब यह है कि मैं रनटाइम सरणी वर्ग नहीं बना सकता, लेकिन मैं अभी भी इसकी लोडिंग पैच कर सकता हूं?
+1

ओपी का मुद्दा यह है कि कल्पना यह इंगित करती है कि सरणी कक्षाओं के मामले में, JVM क्लासलोडर का उपयोग करने से बचाता है और कक्षा को सीधे लोड करता है। और यह एक बहुत अच्छा सवाल है। –

+0

हां, मैंने सरणी के तत्व प्रकार (केवल परीक्षण करने के लिए) को लोड करने के उद्देश्य से ऐसा किया। लेकिन इसके बजाय, यह पूरे सरणी को बदल रहा है। – Codoscope

उत्तर

4

आप जेवीएम विनिर्देश के बारे में पूछ रहे हैं, लेकिन आपका परीक्षण java.lang.ClassLoader के व्यवहार को दर्शाता है, जो एक स्वतंत्र वर्ग है जो "invoked by the Java virtual machine to resolve class references" है। यदि JVM एक सरणी वर्ग लोड कर रहा है, तो यह कक्षा लोडर को पूरी तरह से बाईपास कर देगा। यह JVM की अनुमति से प्रदर्शन किया जा सकता एक कस्टम वर्ग लोडर के साथ वर्ग लोड करने का प्रयास:

Class<?> clazz = Class.forName("[[Lcom.foo.Test;", true, new ClassLoader() { 
    @Override 
    public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { 
     System.out.println("Loading " + name); 
     return super.loadClass(name, resolve); 
    } 
}); 
System.out.println(clazz); 

आउटपुट:

 
Loading com.foo.Test 
class [[Lcom.foo.Test; 

आप देख सकते हैं, घटक प्रकार शुरू में वर्ग लोडर के माध्यम से भरी हुई है , लेकिन सरणी प्रकारों को पूरी तरह से लोड कर रहे हैं।

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