java अज्ञात वर्ग के पैरामीटर कैसे पास करें?




anonymous-class (9)

मैंने सोचा था कि गुमनाम वर्ग मूल रूप से लैम्ब्डा की तरह थे लेकिन बदतर वाक्यविन्यास के साथ ... यह सच साबित हुआ लेकिन वाक्यविन्यास भी बदतर है और स्थानीय वर्गों को उस वर्ग में खून बहने के कारण (क्या होना चाहिए) का कारण बनता है।

आप माता-पिता वर्ग के क्षेत्र में उन्हें बनाकर अंतिम अंतिम चर तक पहुंच सकते हैं।

उदाहरण के लिए

इंटरफेस:

public interface TextProcessor
{
    public String Process(String text);
}

वर्ग:

private String _key;

public String toJson()
{
    TextProcessor textProcessor = new TextProcessor() {
        @Override
        public String Process(String text)
        {
            return _key + ":" + text;
        }
    };

    JSONTypeProcessor typeProcessor = new JSONTypeProcessor(textProcessor);

    foreach(String key : keys)
    {
        _key = key;

        typeProcessor.doStuffThatUsesLambda();
    }

मुझे नहीं पता कि उन्होंने जावा 8 में इसे हल किया है (मैं ईई दुनिया में फंस गया हूं और अभी तक 8 नहीं मिला है) लेकिन सी # में यह ऐसा दिखाई देगा:

    public string ToJson()
    {
        string key = null;
        var typeProcessor = new JSONTypeProcessor(text => key + ":" + text);

        foreach (var theKey in keys)
        {
            key = theKey;

            typeProcessor.doStuffThatUsesLambda();
        }
    }

आपको सी # में एक अलग इंटरफ़ेस की आवश्यकता नहीं है ... मुझे याद आती है! मैं खुद को जावा में खराब डिजाइन कर रहा हूं और खुद को दोहराता हूं क्योंकि जावा में कोड की जटिलता को आप को पुन: उपयोग करने के लिए कुछ जोड़ना है, बस कॉपी और पेस्ट करने से भी बदतर है।

क्या पैरामीटर पास करना संभव है, या अज्ञात वर्ग में बाहरी पैरामीटर तक पहुंचना संभव है? उदाहरण के लिए:

int myVariable = 1;

myButton.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        // How would one access myVariable here?
    }
});

क्या श्रोता के लिए मेरे वर्चुअल तक पहुंचने का कोई तरीका है या श्रोता को वास्तविक नामित वर्ग के रूप में बनाए बिना मेरा वरीयता प्राप्त किया जा सकता है?


हां, एक प्रारंभकर्ता विधि जोड़कर जो 'यह' देता है, और तुरंत उस विधि को कॉल करता है:

int myVariable = 1;

myButton.addActionListener(new ActionListener() {
    private int anonVar;
    public void actionPerformed(ActionEvent e) {
        // How would one access myVariable here?
        // It's now here:
        System.out.println("Initialized with value: " + anonVar);
    }
    private ActionListener init(int var){
        anonVar = var;
        return this;
    }
}.init(myVariable)  );

कोई 'अंतिम' घोषणा की आवश्यकता नहीं है।


तकनीकी रूप से, नहीं, क्योंकि अज्ञात कक्षाओं में रचनाकार नहीं हो सकते हैं।

हालांकि, कक्षाएं स्कोप युक्त चर को संदर्भित कर सकती हैं। अज्ञात वर्ग के लिए ये अंतिम श्रेणी (एसएस) या स्थानीय चर से आवृत्ति चर हो सकते हैं जो अंतिम चिह्नित हैं।

संपादित करें : जैसा कि पीटर ने बताया, आप गुमनाम वर्ग के सुपरक्लास के निर्माता को पैरामीटर भी पास कर सकते हैं।


मेरा समाधान एक विधि का उपयोग करना है जो कार्यान्वित अनाम वर्ग लौटाता है। विधि के लिए नियमित तर्क पारित किए जा सकते हैं और अज्ञात वर्ग के भीतर उपलब्ध हैं।

उदाहरण के लिए: (कुछ जीडब्ल्यूटी कोड से टेक्स्ट बॉक्स में बदलाव को संभालने के लिए):

/* Regular method. Returns the required interface/abstract/class
   Arguments are defined as final */
private ChangeHandler newNameChangeHandler(final String axisId, final Logger logger) {

    // Return a new anonymous class
    return new ChangeHandler() {
        public void onChange(ChangeEvent event) {
            // Access method scope variables           
            logger.fine(axisId)
        }
     };
}

इस उदाहरण के लिए, नई अनाम कक्षा-विधि का संदर्भ दिया जाएगा:

textBox.addChangeHandler(newNameChangeHandler(myAxisName, myLogger))

या , ओपी की आवश्यकताओं का उपयोग कर:

private ActionListener newActionListener(final int aVariable) {
    return new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            System.out.println("Your variable is: " + aVariable);
        }
    };
}
...
int myVariable = 1;
newActionListener(myVariable);

आप सादे लैम्बडास का उपयोग कर सकते हैं ("लैम्ब्डा अभिव्यक्ति चर को कैप्चर कर सकते हैं")

int myVariable = 1;
ActionListener al = ae->System.out.println(myVariable);
myButton.addActionListener( al );

या यहां तक ​​कि एक समारोह

Function<Integer,ActionListener> printInt = 
    intvar -> ae -> System.out.println(intvar);

int myVariable = 1;
myButton.addActionListener( printInt.apply(myVariable) );

फंक्शन का उपयोग सजावट करने वालों और एडाप्टर को दोबारा करने का एक शानदार तरीका है, यहां देखें

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


यह जादू करेगा

int myVariable = 1;

myButton.addActionListener(new ActionListener() {

    int myVariable;

    public void actionPerformed(ActionEvent e) {
        // myVariable ...
    }

    public ActionListener setParams(int myVariable) {

        this.myVariable = myVariable;

        return this;
    }
}.setParams(myVariable));

किसी बाहरी चर में कुछ मान डालने का एक आसान तरीका (अनामिक वर्ग के लिए नहीं है) कितना फोला है!

इसी तरह यदि आप बाहरी चर के मान प्राप्त करना चाहते हैं तो आप एक विधि बना सकते हैं जो आप चाहते हैं कि वापस लौटाएं!

public class Example{

    private TypeParameter parameter;

    private void setMethod(TypeParameter parameter){

        this.parameter = parameter;

    }

    //...
    //into the anonymus class
    new AnonymusClass(){

        final TypeParameter parameterFinal = something;
        //you can call setMethod(TypeParameter parameter) here and pass the
        //parameterFinal
        setMethod(parameterFinal); 

        //now the variable out the class anonymus has the value of
        //of parameterFinal

    });

 }

हाँ। आप चरम पर कब्जा कर सकते हैं, आंतरिक कक्षा के लिए दृश्यमान। एकमात्र सीमा यह है कि इसे अंतिम होना चाहिए


अन्य लोगों ने पहले ही जवाब दिया है कि अज्ञात वर्ग केवल अंतिम चर तक पहुंच सकते हैं। लेकिन वे सवाल को छोड़ देते हैं कि मूल चर गैर-फाइनल कैसे रखें। एडम Mlodzinski एक समाधान दिया लेकिन सुंदर bloated है। समस्या के लिए एक बहुत आसान समाधान है:

यदि आप नहीं चाहते हैं कि मेरी myVariable अंतिम हो, तो आपको इसे एक नए दायरे में लपेटना होगा जहां इससे कोई फर्क नहीं पड़ता, अगर यह अंतिम है।

int myVariable = 1;

{
    final int anonVar = myVariable;

    myButton.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            // How would one access myVariable here?
            // Use anonVar instead of myVariable
        }
    });
}

एडम Mlodzinski अपने जवाब में कुछ और नहीं करता है लेकिन अधिक कोड के साथ।





anonymous-class