जावा में सिंथेटिक क्लास


143

जावा में सिंथेटिक क्लास क्या है? इसका उपयोग क्यों किया जाना चाहिए? मुझे इसे कैसे प्रयोग में लाना है?


1
सभी "आपके कोड में नहीं" उत्तर जावा 8 के साथ पुराने हैं, क्योंकि लैम्ब्डा को सिंथेटिक (अनाम नहीं) कक्षाओं के रूप में लागू किया जा सकता है।
ऑरेंजडॉग

निष्पक्ष होने के लिए, एक लैम्ब्डा अभी भी "कड़ाई" नहीं है जो आपके कोड के भीतर स्पष्ट रूप से परिभाषित एक वर्ग है। तो, "आपके कोड में नहीं" अभी भी मान्य है। संकलक आपके कोड में स्पष्ट परिभाषा के बिना आपके लिए सिंथेटिक कक्षाएं उत्पन्न करता है।
मानदोस्तरा

जवाबों:


15

उदाहरण के लिए, जब आपके पास एक स्विच स्टेटमेंट होता है, तो जावा एक वैरिएबल बनाता है जो $ से शुरू होता है। यदि आप इसका एक उदाहरण देखना चाहते हैं, तो उस वर्ग के जावा प्रतिबिंब में झांकना जिसमें उसका स्विच स्टेटमेंट है। जब आप कक्षा में कहीं भी कम से कम एक स्विच स्टेटमेंट रखते हैं, तो आप इन चरों को देखेंगे।

आपके प्रश्न का उत्तर देने के लिए, मेरा मानना ​​है कि आप सिंथेटिक कक्षाओं में (प्रतिबिंब के अलावा) का उपयोग करने में सक्षम हैं।

यदि आप एक ऐसे वर्ग का विश्लेषण कर रहे हैं जिसके बारे में आपको कुछ भी पता नहीं है (प्रतिबिंब के माध्यम से) और उस वर्ग के बारे में बहुत विशिष्ट और निम्न-स्तरीय चीजों को जानने की जरूरत है, तो आप जावा प्रतिबिंब विधियों का उपयोग करके समाप्त हो सकते हैं जो सिंथेटिक कक्षाओं के साथ करना है। यहां केवल "उपयोग" को अपने कोड में उचित रूप से उपयोग करने के लिए वर्ग के बारे में अधिक जानकारी प्राप्त करना है।

(यदि आप ऐसा कर रहे हैं, तो आप शायद कुछ प्रकार के ढांचे का निर्माण कर रहे हैं जो अन्य डेवलपर्स उपयोग कर सकते हैं।)

अन्यथा, यदि आप प्रतिबिंब का उपयोग नहीं कर रहे हैं, तो सिंथेटिक कक्षाओं का कोई व्यावहारिक उपयोग नहीं है जो मुझे पता है।


1
हां, नमूना कोड अच्छा होगा यदि आप एक उदाहरण प्रदान कर सकते हैं /
नैनोफारड

36
इस सवाल का जवाब नहीं है।
दाऊद इब्न करीम

स्विच केस के लिए, मुझे यकीन नहीं है कि अगर यह हर स्विच के लिए होता है, लेकिन मैंने इसे एनम के साथ स्विच के लिए मनाया है; संकलक एकल स्थिर क्षेत्र के साथ अनाम वर्ग उत्पन्न करता है जो एक मैपिंग Enum.ordinal () -> 1, 2, 3 प्रदान करता है (ताकि अंतराल के बिना एक अनुक्रम), और फिर एक लुकअपस्विच निर्देश इस क्रम पर स्विच चलाता है, सीधे नहीं अध्यादेशों पर।
रदिम वंस

106

जावा में रनटाइम पर कक्षाएं बनाने की क्षमता है। इन वर्गों को सिंथेटिक क्लास या डायनेमिक प्रॉक्सी के रूप में जाना जाता है।

अधिक जानकारी के लिए http://java.sun.com/j2se/1.5.0/docs/guide/reflection/proxy.html देखें ।

अन्य ओपन-सोर्स लाइब्रेरी, जैसे सीजीएलआईबी और एएसएम भी आपको सिंथेटिक कक्षाएं उत्पन्न करने की अनुमति देते हैं, और जेआरई के साथ प्रदान किए गए पुस्तकालयों की तुलना में अधिक शक्तिशाली हैं।

सिंथेटिक कक्षाओं का उपयोग एओपी (एस्पेक्ट ओरिएंटेड प्रोग्रामिंग) पुस्तकालयों जैसे स्प्रिंग एओपी और एस्पेक्टज, साथ ही ओआरएम पुस्तकालयों जैसे हाइबरनेट द्वारा किया जाता है।


6
डायनेमिक प्रॉक्सिस सिन्थेटिक क्लासेस नहीं हैं। प्रूफ़:Proxy.newProxyInstance(Runnable.class.getClassLoader(), new Class[]{Runnable.class}, (proxy, method, args1) -> null).getClass().isSynthetic() == false
मिहा_x64

3
के लिए javadoc java.lang.reflect.Member#isSyntheticकहता है: यदि यह सदस्य संकलक द्वारा पेश किया गया था तो वापस लौटाता है; अन्यथा गलत है।
गिलियूम हस्टा

मेरा मानना ​​है कि java.lang.reflect.Member#isSyntheticमूल प्रश्न के लिए javadoc अप्रासंगिक है। सदस्य क्षेत्र, निर्माता और विधियाँ हैं। मूल प्रश्न सिंथेटिक कक्षाओं के बारे में था , न कि सिंथेटिक सदस्यों के बारे में। जावा 8 में, लैम्ब्डा अभिव्यक्तियाँ सिंथेटिक कक्षाओं को जन्म देती हैं - मुझे यकीन नहीं है कि वे और कौन सी परिस्थितियाँ पैदा कर सकते हैं।
फ्रा जेरेमी क्रिग

54

वैसे मुझे Google पर पहले प्रश्न का उत्तर मिला:

एक वर्ग को सिंथेटिक के रूप में चिह्नित किया जा सकता है यदि यह संकलक द्वारा उत्पन्न होता है, अर्थात यह स्रोत कोड में प्रकट नहीं होता है।

यह सिर्फ एक मूल परिभाषा है लेकिन मैंने इसे एक फोरम थ्रेड में पाया और कोई स्पष्टीकरण नहीं था। फिर भी एक बेहतर की तलाश ...


15

सिंथेटिक कक्षाएं / तरीके / क्षेत्र:

ये चीजें VM के लिए महत्वपूर्ण हैं। निम्नलिखित कोड स्निपेट पर एक नज़र डालें:

class MyOuter {

  private MyInner inner;

  void createInner() {
    // The Compiler has to create a synthetic method
    // to construct a new MyInner because the constructor
    // is private.
    // --> synthetic "constructor" method
    inner = new MyInner();

    // The Compiler has to create a synthetic method
    // to doSomething on MyInner object because this
    // method is private.
    // --> synthetic "doSomething" method
    inner.doSomething();
  }

  private class MyInner {
    // the inner class holds a syntetic ref_pointer to
    // the outer "parent" class
    // --> synthetic field
    private MyInner() {
    }
    private void doSomething() {
    }
  }
}

2
@CiroSantilli 烏坎 iro 2016 事件 ill ill, नहीं, केवल सिंथेटिक अभिगम विधि।
मिहा_x64

8

इस चर्चा के अनुसार , हालांकि, भाषा विनिर्देश वर्गों के लिए एक "SStthetic "भविष्यवाणी का वर्णन करता है, लेकिन यह कार्यान्वयन द्वारा बहुत अधिक अनदेखा किया जाता है और गतिशील प्रॉक्सी या अनाम कक्षाओं के लिए उपयोग नहीं किया जाता है। नेस्टेड कक्षाओं को लागू करने के लिए सिंथेटिक फ़ील्ड और कंस्ट्रक्टर का उपयोग किया जाता है (बाइट कोड में नेस्टेड क्लास की अवधारणा नहीं है, केवल स्रोत कोड में)।

मुझे लगता है कि सिंथेटिक कक्षाओं की अवधारणा केवल उपयोगी साबित नहीं हुई है, अर्थात कोई भी परवाह नहीं करता है कि कोई वर्ग सिंथेटिक है या नहीं। फ़ील्ड और विधियों के साथ, इसका उपयोग संभवतः एक ही स्थान पर किया जाता है: यह निर्धारित करने के लिए कि IDE क्लास संरचना दृश्य में क्या दिखाना है - आप सामान्य तरीके और फ़ील्ड दिखाना चाहते हैं, लेकिन सिंथेटिक लोग नेस्टेड कक्षाओं का अनुकरण नहीं करते थे। OTOH, आप अनाम कक्षाओं को दिखाना चाहते हैं।


@OrangeDog: हाँ, यही मैंने लिखा है।
माइकल बोर्गवर्ड

यह उत्तर जावा 8 से पुराना प्रतीत होता है - लंबोदा और विधि संदर्भ इस सुविधा का उपयोग करते हैं। मैंने एक उत्तर
हल्क

7

वे JVM द्वारा उस समय बनाए जाते हैं जब वे डीबगिंग उद्देश्य के लिए आंतरिक वर्ग के निजी सदस्यों को आमंत्रित करते हैं

इसके निष्पादन उद्देश्य के लिए रन टाइम के दौरान जेवीएम द्वारा बनाई गई विधियों, क्षेत्रों, वर्ग को सिंथेटिक कहा जाता है

http://www.javaworld.com/article/2073578/java-s-synthetic-methods.html

http://javapapers.com/core-java/java-synthetic-class-method-field/


मुझे लगता है कि आप संकलन समय पर मतलब है, और क्रम में नहीं।
Mostowski पतन

@ सथिस, क्या आपका मतलब जेवैक था, जेवीएम नहीं?
मिहा_x64

3

रनटाइम पर इंटरफेस या अमूर्त कक्षाओं के कार्यान्वयन को बनाने के लिए ईज़ीमॉक द्वारा सिंथेटिक क्लास या डायनेमिक प्रॉक्सी का भी उपयोग किया जाता है।

http://www.easymock.org/


2

जब जावा कंपाइलर कुछ निर्माणों को संकलित करता है, जैसे कि आंतरिक वर्ग, तो यह सिंथेटिक निर्माण बनाता है ; ये वर्ग, विधियाँ, फ़ील्ड्स और अन्य निर्माण हैं जिनके स्रोत कोड में संबंधित निर्माण नहीं है।
उपयोग: सिंथेटिक निर्माण जावा संकलक को जेवीएम में बदलाव के बिना नई जावा भाषा सुविधाओं को लागू करने में सक्षम बनाते हैं। हालांकि, सिंथेटिक निर्माण विभिन्न जावा कंपाइलर कार्यान्वयन के बीच भिन्न हो सकते हैं, जिसका अर्थ है कि .class फाइलें अलग-अलग कार्यान्वयन के बीच भी भिन्न हो सकती हैं।
संदर्भ: docs.oracle.com


2

जैसा कि विभिन्न उत्तर पहले ही इंगित कर चुके हैं, संकलक को विभिन्न निर्माणों (कक्षाओं सहित) को उत्पन्न करने की अनुमति है जो सीधे मेमोरी कोड में कुछ के अनुरूप नहीं हैं। इन्हें सिंथेटिक के रूप में चिह्नित किया जाना है:

13.1। एक द्विआधारी का रूप

एक वर्ग या इंटरफ़ेस के लिए एक द्विआधारी प्रतिनिधित्व में निम्नलिखित सभी शामिल होने चाहिए:
[...]
11. जावा कंपाइलर द्वारा उत्सर्जित एक निर्माण को सिंथेटिक के रूप में चिह्नित किया जाना चाहिए यदि यह स्रोत कोड में स्पष्ट रूप से या अंतर्निहित रूप से घोषित निर्माण के अनुरूप नहीं है। , जब तक उत्सर्जित निर्माण एक वर्ग आरंभीकरण विधि (JVMS )2.9) है।
[...]

जैसा कि @Holger द्वारा एक अन्य प्रश्न के लिए एक टिप्पणी में बताया गया है , ऐसे निर्माणों के लिए प्रासंगिक उदाहरण विधि संदर्भ और लंबोदर का प्रतिनिधित्व करने वाली कक्षा वस्तुएं हैं:

System.out.println(((Runnable) System.out::println).getClass().isSynthetic());
System.out.println(((Runnable) () -> {}).getClass().isSynthetic());

आउटपुट:

true
true

जबकि यह स्पष्ट रूप से उल्लेखित नहीं है, यह 15.27.4 से निम्नानुसार है लंबोदर एक्सप्रेशंस का रन-टाइम मूल्यांकन :

लैम्ब्डा अभिव्यक्ति का मूल्य निम्न गुणों के साथ एक वर्ग के उदाहरण के लिए एक संदर्भ है: [...]

और विधि संदर्भों के लिए लगभग समान शब्दांकन ( 15.13.3। विधि संदर्भों का रन-टाइम मूल्यांकन )।

जैसा कि इस कोड को स्पष्ट रूप से स्रोत कोड में कहीं भी उल्लेख नहीं किया गया है, इसे सिंथेटिक होना है।


1

अगर मुझे यह सही लगता है, तो यह स्पष्ट नाम देने के बिना, एक सिंथेटिक वर्ग मक्खी पर उत्पन्न होता है। उदाहरण के लिए:

//...
Thread myThread = new Thread() {
         public void run() {
           // do something ...
         }
       };
myThread.start();
//...

यह थ्रेड का एक सिंथेटिक उपवर्ग बनाता है और इसकी रन () विधि को ओवरराइड करता है, फिर इसे इंस्टेंट करता है और इसे शुरू करता है।


3
मुझे लगा कि यह अनाम आंतरिक वर्ग है
कुमार अभिनव

2
मुझे @KumarAbhinav से सहमत होना होगा। सभी अनाम आंतरिक वर्ग सिंथेटिक नहीं हैं। देखें: xinotes.net/notes/note/1339
bvdb

अनाम आंतरिक कक्षाएं Oracle JDK 1.8.0_45 पर सिंथेटिक कक्षाएं उत्पन्न नहीं करती हैं, वे प्रकार के नामों के साथ अलग-अलग गैर-सिंथेटिक कक्षाएं उत्पन्न करती हैं Outer$1.class
सिरो सेंटिल्ली 郝海东 冠状 iro i 法轮功 '

1

एक सिंथेटिक वर्ग आपके कोड में नहीं दिखाई देता है: यह कंपाइलर द्वारा बनाया गया है। उदा। जावा में कंपाइलर द्वारा बनाई गई एक पुल विधि आमतौर पर सिंथेटिक होती है।

public class Pair<T> {
    private T first;
    private T second;
    public void setSecond(T newValue) {
        second = newValue;
    }
}


public class DateInterval extends Pair<String> {
    public void setSecond(String second) {
        System.out.println("OK sub");
    }

    public static void main(String[] args) throws NoSuchFieldException, SecurityException {
        DateInterval interval = new DateInterval();
        Pair pair = interval;
        pair.setSecond("string1");
    }
}

कमांड का उपयोग करके javap -verbose DateInterval, आप एक पुल विधि देख सकते हैं:

public void setSecond(java.lang.Object);
flags: ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC

यह संकलक द्वारा बनाया गया था; यह आपके कोड में दिखाई नहीं देता है।


1

जावा में सिंथेटिक क्लास क्या है?

एक syntheticक्लास जावा कंपाइलर.class द्वारा बनाई गई फ़ाइल है और यह स्रोत कोड में मौजूद नहीं है।

syntheticकक्षा का उदाहरण उपयोग : अनाम आंतरिक वर्ग

  • java.text.DigitList $ 1 एक syntheticवर्ग है और यह java.text.DigitList के अंदर एक अनाम आंतरिक वर्ग है
  • और कोई स्रोत कोड फ़ाइल की तरह नाम नहीं है, DigitList$1.javaलेकिन यह एक आंतरिक फ़ाइल हैDigitList.java

इसका उपयोग क्यों किया जाना चाहिए?

यह .classफाइल बनाने के लिए जावा कंपाइलर लॉजिक के अंदर एक मैकेनिज्म है

मुझे इसे कैसे प्रयोग में लाना है?

नहीं, डेवलपर्स सीधे इसका उपयोग नहीं करते हैं।

जावा कंपाइलर फ़ाइल syntheticउत्पन्न करने के लिए उपयोग करता .classहै, और फिर जेवीएम .classप्रोग्राम लॉजिक को निष्पादित करने के लिए फ़ाइल पढ़ता है।

अधिक जानकारी

  • यह लेखsynthetic विवरण में वर्ग की व्याख्या करता है
  • यह लिंक JDKsynthetic में सभी वर्ग निकासों को सूचीबद्ध करता है

लेख बहुत उपयोगी है, धन्यवाद
JasonMing

0

सिंथेटिक निर्माण वर्ग, विधियाँ, क्षेत्र आदि होते हैं जिनके स्रोत कोड में संबंधित निर्माण नहीं होता है। जेवीएम में बदलाव के बिना नए जावा लैंग्वेज फीचर्स को लागू करने के लिए सिंथेटिक कंस्ट्रक्ट जावा कंपाइलर्स को सक्षम करते हैं। हालांकि, सिंथेटिक निर्माण विभिन्न जावा कंपाइलर कार्यान्वयन के बीच भिन्न हो सकते हैं, जिसका अर्थ है कि .class फाइलें अलग-अलग कार्यान्वयन के बीच भी भिन्न हो सकती हैं।


1
-1। बहुत ही पाठ, शब्दशः, उत्तर में पोस्ट किया गया था एक साल पहले तुम्हारा [ stackoverflow.com/a/24271953/1144395] , और फिर भी उस उत्तर ने आधिकारिक संदर्भ का हवाला दिया जहां पाठ की उत्पत्ति हुई, और आसान पढ़ने के लिए प्रारूपण प्रदान किया। । कृपया स्पष्ट रूप से डुप्लिकेट उत्तरों के साथ लालची प्रश्नों को न करें।
नाकी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.