जब मैं जावप के साथ एक enum को अलग करता हूं, तो enum के अंतर्निहित कन्स्ट्रक्टर तर्क गुम होने लगते हैं, और मैं यह नहीं समझ सकता कि क्यों।जवाप के साथ अलग किया गया एनम कन्स्ट्रक्टर तर्क नहीं दिखाता
यहाँ एक enum है:
enum Foo { X }
मैं संकलन और एकत्रित न इस इस आदेश के साथ (जावा 8u60 पर):
javac Foo.java && javap -c -p Foo
और यहाँ है उत्पादन मैं:
final class Foo extends java.lang.Enum<Foo> {
public static final Foo X;
private static final Foo[] $VALUES;
public static Foo[] values();
Code:
0: getstatic #1 // Field $VALUES:[LFoo;
3: invokevirtual #2 // Method "[LFoo;".clone:()Ljava/lang/Object;
6: checkcast #3 // class "[LFoo;"
9: areturn
public static Foo valueOf(java.lang.String);
Code:
0: ldc #4 // class Foo
2: aload_0
3: invokestatic #5 // Method java/lang/Enum.valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
6: checkcast #4 // class Foo
9: areturn
private Foo(); // <--- here
Code:
0: aload_0
1: aload_1
2: iload_2
3: invokespecial #6 // Method java/lang/Enum."<init>":(Ljava/lang/String;I)V
6: return
static {};
Code:
0: new #4 // class Foo
3: dup
4: ldc #7 // String X
6: iconst_0
7: invokespecial #8 // Method "<init>":(Ljava/lang/String;I)V
10: putstatic #9 // Field X:LFoo;
13: iconst_1
14: anewarray #4 // class Foo
17: dup
18: iconst_0
19: getstatic #9 // Field X:LFoo;
22: aastore
23: putstatic #1 // Field $VALUES:[LFoo;
26: return
}
मेरा भ्रम निजी कन्स्ट्रक्टर के साथ होता है जो प्रत्येक enum स्थिरता को तुरंत चालू करने के लिए उपयोग किया जाता है। Disassembly दिखाता है कि यह कोई तर्क नहीं लेता है (private Foo();
), लेकिन यह निश्चित रूप से तर्क लेता है। उदाहरण के लिए, आप load
पास किए गए एनम निरंतर नाम और क्रमिक, साथ ही साथ this
पॉइंटर पढ़ने के निर्देशों को देख सकते हैं, और उन्हें the superclass constructor पर भेज सकते हैं, जिसके लिए उन्हें आवश्यकता होती है। स्थिर प्रारंभकर्ता ब्लॉक में कोड यह भी दिखाता है कि यह कन्स्ट्रक्टर को कॉल करने से पहले उन तर्कों को स्टैक पर धक्का देता है।
अब मैं मान लिया होता तो यह सिर्फ javap में एक अस्पष्ट बग था, लेकिन जब मैं ग्रहण के संकलक के साथ ठीक उसी enum संकलन और कि javap का उपयोग कर एकत्रित न, निर्माता तर्क से पता चला रहे हैं को छोड़कर बिल्कुल वैसा ही है:
final class Foo extends java.lang.Enum<Foo> {
public static final Foo X;
private static final Foo[] ENUM$VALUES;
static {};
Code:
0: new #1 // class Foo
3: dup
4: ldc #12 // String X
6: iconst_0
7: invokespecial #13 // Method "<init>":(Ljava/lang/String;I)V
10: putstatic #17 // Field X:LFoo;
13: iconst_1
14: anewarray #1 // class Foo
17: dup
18: iconst_0
19: getstatic #17 // Field X:LFoo;
22: aastore
23: putstatic #19 // Field ENUM$VALUES:[LFoo;
26: return
private Foo(java.lang.String, int); // <--- here
Code:
0: aload_0
1: aload_1
2: iload_2
3: invokespecial #23 // Method java/lang/Enum."<init>":(Ljava/lang/String;I)V
6: return
public static Foo[] values();
Code:
0: getstatic #19 // Field ENUM$VALUES:[LFoo;
3: dup
4: astore_0
5: iconst_0
6: aload_0
7: arraylength
8: dup
9: istore_1
10: anewarray #1 // class Foo
13: dup
14: astore_2
15: iconst_0
16: iload_1
17: invokestatic #27 // Method java/lang/System.arraycopy:(Ljava/lang/Object;ILjava/lang/Object;II)V
20: aload_2
21: areturn
public static Foo valueOf(java.lang.String);
Code:
0: ldc #1 // class Foo
2: aload_0
3: invokestatic #35 // Method java/lang/Enum.valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
6: checkcast #1 // class Foo
9: areturn
}
मेरा प्रश्न है: क्या शारीरिक रूप से एक javac संकलित enum और एक एक्लिप्स संकलित enum कि javac संकलित enum के लिए निर्माता तर्क नहीं दिखाने के लिए javap का कारण बनता है के बीच अलग है? और क्या यह एक बग है (जावप में, जावैक में, या ग्रहण में)?
अनुमान में, '-g' ध्वज की सेटिंग (डीबगिंग जानकारी की नियंत्रण जनरेशन)। – CPerkins
@CPerkins अच्छी परिकल्पना लेकिन मैंने '-g' की तुलना की (सभी डीबगिंग जानकारी उत्पन्न करें) और '-g: none' (कोई डिबगिंग जानकारी उत्पन्न नहीं करें) और ऐसा कोई फर्क नहीं पड़ता। – Boann
क्या आपने '-v' (verbose) ध्वज को आजमाया था? इसे कम से कम आपको कन्स्ट्रक्टर का वर्णनकर्ता दिखाना चाहिए। मेरा अनुमान है कि 'जावैक' पहले पैरामीटर 'मंडेटेड' को चिह्नित करता है, जो उन्हें 'जावप' को छोड़ सकता है। – Clashsoft