2013-01-05 18 views
11

मुझे प्रतिबिंब के साथ काम करते समय दिलचस्प चीज़ मिली। मैंने सरल वर्ग और उनके संशोधक के रचनाकारों को पुनः प्राप्त करने का प्रयास किया।अप्रत्याशित "क्षणिक" कन्स्ट्रक्टर संशोधक

Class<?> clazz = Test.class; 
Constructor<?>[] ctors = clazz.getDeclaredConstructors(); 
for (Constructor<?> ctor : ctors) {   
    int mod = ctor.getModifiers(); 
    /*if not package-private modifier*/ 
    if(mod!=0) { 
     System.out.println(Modifier.toString(mod))); 
    } 
} 

परिणाम है::

public class Test { 
    public Test(Object... args) {} 
} 

यहाँ निर्माता संशोधक को पुनः प्राप्त करने कोड है

public transient 

अगर मैं नहीं चर मापदंडों निर्माता को पारित, लेकिन सिर्फ सरणी, यह ठीक है।

public class Test { 
    public Test(Object[] args) {} 
} 

परिणाम है:

public 

एक ही निर्माता संशोधक की परवाह किए बिना होता है (सार्वजनिक, संरक्षित, निजी) या मापदंडों प्रकार (आदिम या संदर्भ)। यह कैसे हो सकता है, जबकि "क्षणिक" कन्स्ट्रक्टर के लिए वैध संशोधक नहीं है?

उत्तर

17

एक्सेस संशोधक कक्षा फ़ाइल के अंदर बिट मास्क के रूप में एन्कोड किए गए हैं। JVM spec कुछ बिट्स को अलग-अलग अर्थ निर्दिष्ट करता है कि वे एक विधि संशोधक या फ़ील्ड संशोधक में दिखाई देते हैं या नहीं। बिट 7 (0x0080) एक ऐसा बिट है।

For methods:

ACC_VARARGS 0x0080 Declared with variable number of arguments. 

For fields:

ACC_TRANSIENT 0x0080 Declared transient; not written or read by a persistent 
         object manager. 

आप एक विधि पर देख रहे हैं के बाद से, यह संशोधक की सही व्याख्या ACC_VARARGS और नहीं ACC_TRANSIENT है।

हालांकि, Modifier कक्षा केवल जेवीएम स्पेक में परिभाषित संशोधकों के उप-समूह से निपटने में सक्षम दिखाई देती है। क्योंकि यह सब int है, यह ACC_VARARGS और ACC_TRANSIENT को अलग करने में असमर्थ है।

+1

क्या यह 'toString' विधि की बग के रूप में गिना जाता है? –

+1

@JanDvorak: मुझे यकीन नहीं है। जैसे-जैसे चीजें खड़ी होती हैं, 'मॉडिफायर' क्लास केवल जेवीएम स्पेक में परिभाषित संशोधकों के सबसेट से निपटने में सक्षम दिखाई देती है (क्योंकि यह समान मूल्य वाले संशोधक के बीच अंतर करने में असमर्थ है)। – NPE

+1

मैं सोच रहा हूं - बिट मान वास्तव में क्यों टकराते हैं? क्या यह JVM devs से एक निरीक्षण नहीं है? –

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