एक कृत्रिम तत्व किसी भी तत्व है कि एक संकलित वर्ग फ़ाइल में मौजूद नहीं बल्कि स्रोत कोड में से संकलित किया गया है है। सिंथेटिक होने के लिए तत्व की जांच करके, आप उन तत्वों के लिए ऐसे तत्वों का भेद करने की अनुमति देते हैं जो कोड को प्रतिबिंबित करते हैं। यह निश्चित रूप से उन सभी पुस्तकालयों के लिए प्रासंगिक है जो प्रतिबिंब का उपयोग करते हैं लेकिन यह अन्य उपकरणों जैसे आईडीई के लिए भी प्रासंगिक है जो आपको सिंथेटिक तरीकों को कॉल करने या सिंथेटिक कक्षाओं के साथ काम करने की अनुमति नहीं देते हैं। अंत में, जावा संकलक के लिए भी संकलन के दौरान कोड को सत्यापित करने के लिए यह भी महत्वपूर्ण है कि कभी भी सिंथेटिक तत्वों का उपयोग न करें। सिंथेटिक तत्वों का उपयोग केवल जावा रनटाइम को खुश करने के लिए किया जाता है जो केवल वितरित कोड को संसाधित करता है (और सत्यापित करता है) जहां यह किसी भी अन्य तत्व के समान सिंथेटिक तत्वों का व्यवहार करता है।
आप पहले से ही एक उदाहरण है जहां सिंथेटिक तत्वों जावा संकलक द्वारा डाला जाता है के रूप में इनर क्लासों उल्लेख किया है, इसलिए हमें इस तरह के एक वर्ग पर ध्यान दें:
class Foo {
private String foo;
class Bar {
private Bar() { }
String bar() {
return foo;
}
}
Bar bar() {
return new Bar();
}
}
यह बिल्कुल ठीक है, लेकिन सिंथेटिक तत्वों के बिना संकलित, यह होगा एक जेवीएम द्वारा मना कर दिया गया है जो आंतरिक कक्षाओं के बारे में कुछ नहीं जानता है। जावा कम्पाइलर की तरह कुछ करने के लिए ऊपर वर्ग desugares निम्नलिखित:
class Foo {
private String foo;
String access$100() { // synthetic method
return foo;
}
Foo$Bar bar() {
return new Foo$Bar(this, (Foo$1)null);
}
Foo() { } // NON-synthetic, but implicit!
}
class Foo$Bar {
private final Foo $this; // synthetic field
private Foo$Bar(Foo $this) { // synthetic parameter
this.$this = $this;
}
Foo$Bar(Foo $this, Foo$1 unused) { // synthetic constructor
this($this);
}
String bar() {
return $this.access$100();
}
}
class Foo$1 { /*empty, no constructor */ } // synthetic class
के रूप में कहा, JVM इनर क्लासों के बारे में पता नहीं है, लेकिन सदस्यों के निजी उपयोग, यानी एक आंतरिक वर्ग का उपयोग करने में सक्षम नहीं होगा लागू करता है इसके संलग्न वर्ग 'निजी गुण। इस प्रकार, जावा कम्पाइलर अपने गैर दृश्य गुण को बेनकाब करने के क्रम में एक पहुँचा वर्ग के लिए accessors तथाकथित जोड़ने की जरूरत है:
foo
क्षेत्र निजी है और इसलिए केवल Foo
से एक्सेस किया जा सकता है। access$100
विधि इस फ़ील्ड को अपने पैकेज में दिखाती है जिसमें एक आंतरिक कक्षा हमेशा पाई जाती है। यह विधि सिंथेटिक है क्योंकि इसे कंपाइलर द्वारा जोड़ा जाता है।
Bar
कन्स्ट्रक्टर निजी है और इसलिए इसे केवल अपनी कक्षा के भीतर से ही बुलाया जा सकता है। Bar
के उदाहरण को तुरंत चालू करने के लिए, एक और (सिंथेटिक) कन्स्ट्रक्टर को एक उदाहरण के निर्माण का पर्दाफाश करने की आवश्यकता है। हालांकि, रचनाकारों का एक निश्चित नाम होता है (आंतरिक रूप से, उन्हें सभी <init>
कहा जाता है), इस प्रकार हम विधि एक्सेसर्स के लिए तकनीक लागू नहीं कर सकते हैं, जहां हमने उन्हें access$xxx
नाम दिया है। इसके बजाए, हम कृत्रिम प्रकार Foo$1
बनाकर रचनाकार एक्सेसर्स अद्वितीय बनाते हैं।
अपने बाहरी उदाहरण तक पहुंचने के लिए, एक आंतरिक वर्ग को इस उदाहरण के संदर्भ को स्टोर करने की आवश्यकता होती है जो सिंथेटिक फ़ील्ड $this
में संग्रहीत होती है। इस संदर्भ को कन्स्ट्रक्टर में सिंथेटिक पैरामीटर द्वारा आंतरिक आवृत्ति को सौंपने की आवश्यकता है।
सिंथेटिक तत्वों के लिए अन्य उदाहरण वर्गों कि लैम्ब्डा भाव का प्रतिनिधित्व करते हैं, पुल तरीकों जब एक प्रकार-अलग हस्ताक्षरों के साथ तरीकों अधिभावी कर रहे हैं, Proxy
वर्ग या वर्गों Maven जैसे अन्य टूल द्वारा बनाई गई हैं कि के निर्माण बनाता है या क्रम कोड जनरेटर जैसे Byte Buddy (लापरवाही प्लग)।
स्रोत
2014-09-26 08:43:25
संकेत के लिए धन्यवाद। मैंने तदनुसार सवाल अपडेट किया। –
@PeterKofler अपडेट किया गया। –
कहता है "एक वर्ग सदस्य जो स्रोत कोड में प्रकट नहीं होता है उसे सिंथेटिक विशेषता का उपयोग करके चिह्नित किया जाना चाहिए।" क्या इसका मतलब है कि सिंथेटिक सदस्य को '0x1000' एक्सेस संशोधक (' u2 access_flags' में) के साथ भी चिह्नित किया गया है? यह स्पष्ट नहीं है। –