मैं कुछ प्रयोग कर रहे हैं और गलती से एक कोड है, जो बहुत अजीब है लिखा था और मैं यह सब नहीं मिलता था। मैं भी आश्चर्यचकित था कि मैं इसे संकलित कर सकता हूं। यह इस तरह दिखता है:जावा: अंदर तरीकों और चर की परिभाषा enum के निरंतर
Foo.VALUE_2.myMethod();
कारण है, कि संकलक गणन के अंदर ही है कि विधि के लिए दिखेगा:
enum Foo {
VALUE_1 {
public int myVariable = 1;
},
VALUE_2 {
public void myMethod() {
//
}
},
VALUE_3;
}
जैसी उम्मीद थी, यह निम्नलिखित तरीके से इस तरह के एक तत्व का उपयोग करना संभव नहीं है ।
मैं माना है कि यह गणन के बाहर से इन तरीकों और चर का उपयोग करने के संभव नहीं है।
enum Foo {
VALUE(internalVariable) {
int internalVariable = 1;
};
private Foo(int param) {
//
}
}
यह संभव नहीं था इस तरह के एक निर्माण को संकलित करने के: इस कारण से, मैं एक पैरामीट्रिक निर्माता बना सकते हैं और कुछ आंतरिक चर से कॉल करने की कोशिश की। अब मैं सोच रहा था कि अगर इसे एक्सेस करने का कोई तरीका नहीं है तो निरंतर अंदर कुछ परिभाषित करने का क्या मतलब है।
मैं बाहर की जाँच करने के लिए अगर यह किसी तरह से टकरा निरंतर में समान नाम वाले तरीकों के साथ-साथ में शुमार ही बनाने के लिए कोशिश कर रहा था। यह नहीं था!
enum Foo {
VALUE_1 {
int myVariable = 1;
public int myMethod() {
return myVariable;
}
},
VALUE_2 {
//
};
public int myMethod() {
return 0;
}
}
और यहां मजेदार क्षण आता है! मैंने गणना के अंदर myMethod() की कॉल को आगे बढ़ाने की कोशिश की और वास्तव में यह पता लगाया कि यह जावा जादू कैसे काम करता है। विधियों, जिन्हें निरंतर अंदर परिभाषित किया गया है, गणना के भीतर परिभाषित विधियों को ओवरराइड करता है।
Foo.VALUE_1.myMethod(); // Returns 1
Foo.VALUE_2.myMethod(); // Returns 0
हालांकि, हम चर को ओवरराइड नहीं कर सकते हैं, है ना? तो मैं उत्सुक था, यह केवल चर के साथ कैसे काम करता है।
enum Foo {
VALUE_1 {
public int myVariable = 1;
},
VALUE_2 {
//
};
public int myVariable = 0;
}
....
System.out.println(Foo.VALUE_1.myVariable); // Returns 0
System.out.println(Foo.VALUE_2.myVariable); // Returns 0
अब मैं अंत में अपने सवालों के हो रही है:
क्यों अगर मैं इस विधि के बिना निरंतर और बाईं गणन अंदर सार्वजनिक विधि बनाने खाली मैं किसी भी त्रुटि नहीं मिलता है? उस मामले में, विधि मैं सिर्फ बिल्कुल नहीं कहा जा सकता परिभाषित किया। या मैं गलत हूँ?
अद्यतन: मुझे पता है कि गणना इंटरफ़ेस को कार्यान्वित कर सकती है। हालांकि, अगर मेरे पास नहीं है तो विशेष रूप से कहा गया है कि, संपूर्ण कोड व्यर्थ है।
किसी ने इंगित किया कि सामान्य तरीके से भाषा से विधि तक पहुंचा नहीं जा सकता है, फिर भी प्रतिबिंब का उपयोग करना संभव है। खैर ... क्यों हम एक दुर्गम कीवर्ड डिजाइन नहीं है?
inaccessible void magicalMethod() { // }
ऐसी विधि * .class फ़ाइल में संकलित की जाएगी। जब आप इसका उपयोग करना चाहते हैं, तो आपको अपने द्वारा लोड बाइटकोड करना होगा और इसकी व्याख्या करना होगा।
मैं बस नहीं समझ सकता, यह क्यों नहीं पहुंचा जा सकता विधि निर्धारित करना संभव है। एकमात्र कारण मुझे लगता है कि प्रोग्रामर काम कर रहा है और अभी तक इंटरफ़ेस की परिभाषा नहीं है।तो वह सिर्फ एकल विधियों का कोड तैयार कर रहा है और बाद में "उपकरण" कीवर्ड जोड़ देगा। के अलावा यह अजीब है, फिर भी सभी स्थिरांक में ऐसी विधि की आवश्यकता होगी।
मुझे लगता है कि यह त्रुटि के साथ समाप्त होना चाहिए, न केवल अप्रयुक्त विधि के बारे में चेतावनी। आप "कार्यान्वयन" खंड जोड़ने या गणना में विधि को परिभाषित करने के लिए भूल सकते हैं (जो ओवरराइड होगा) और यह महसूस होगा कि पहले उपयोग के बाद ही। जावा बहुत सख्त भाषा है, इसलिए मैं इस व्यवहार की अपेक्षा करता हूं।
अगर मैं सार्वजनिक चर (या फ़ील्ड, अधिक सटीक होने के लिए) बनाते हैं तो मुझे कोई त्रुटि क्यों नहीं मिलती है? इसे किसी भी मामले (बाहर से) में नहीं पहुंचा जा सकता है। इसलिए, संशोधक "सार्वजनिक" यहां कोई समझ नहीं आता है।
अद्यतन: यह दृश्यता संशोधक यहां पूरी तरह से बेकार है को छोड़कर, और अधिक कम पिछले बिंदु के रूप में एक ही बात है। यह वास्तव में कोई फर्क नहीं पड़ता कि यह सार्वजनिक है, या निजी संरक्षित है, क्योंकि आप वैसे भी इसे एक्सेस नहीं कर पाएंगे। मुझे लगता है कि यह एक बग है।
ऐसा क्यों है संभव है (दृश्यता बिना संशोधक) एक वर्ग को परिभाषित, लेकिन इंटरफेस नहीं? हाँ, आप शायद इतनी क्रूर गणना नहीं लिखना चाहेंगे कि आपको निरंतर कक्षाओं को परिभाषित करने और यहां तक कि वहां विरासत का उपयोग करने की आवश्यकता होगी। लेकिन यदि कक्षाओं और अमूर्त वर्गों को परिभाषित करना संभव है, तो यह थोड़ा अजीब लगता है।
अद्यतन: यह निश्चित रूप से कुछ आप नियमित आधार पर आवश्यकता होगी नहीं है, लेकिन मैं है कि यह उपयोगी हो सकता है समझते हैं। लेकिन यह केवल कक्षाओं तक सीमित क्यों है और इंटरफेस भी परिभाषित नहीं किया जा सकता है?
enum Foo { VALUE { class MyClass { // OK } abstract class MyAbstractClass { // OK } interface MyInterface { // FAIL. It won't compile. } } }
क्या आपने कहीं ऐसी कार्यक्षमता का उपयोग किया था? मैं कल्पना कर सकता हूं कि यह उपयोगी हो सकता है, लेकिन यह थोड़ा उलझन में है। इसके अलावा, जब मैं इसके बारे में कुछ संसाधन खोज रहा था, मुझे कुछ भी नहीं मिला।
अद्यतन: मैं कुछ व्यावहारिक उदाहरण एक एनम निरंतर वर्ग निकाय में ओवरराइड विधियों को देखना चाहता हूं। क्या आपने इसे कुछ ओपन-सोर्स प्रोजेक्ट में देखा है?
पर्यावरण:
$ java -version
java version "1.7.0_21"
OpenJDK Runtime Environment (IcedTea 2.3.9) (7u21-2.3.9-0ubuntu0.12.10.1)
OpenJDK 64-Bit Server VM (build 23.7-b01, mixed mode)
अपने समय के लिए और अपने जवाब के लिए धन्यवाद!
आप निर्माता फैक्ट्रीज ओपन सोर्स प्रोजेक्ट में एनम कॉस्टेंट के अंदर ओवरराइड विधियों का व्यावहारिक उदाहरण पा सकते हैं: http://www.github.com/raspacorp/maker – raspacorp