जावा: क्लास


112

मेरे पास एक जावा प्रोग्राम है जो इस तरह दिखता है।

public class LocalScreen {

   public void onMake() {
       aFuncCall(LocalScreen.this, oneString, twoString);
   }
}

में क्या LocalScreen.thisमतलब है aFuncCall?

जवाबों:


169

LocalScreen.thisthisएनक्लोजिंग क्लास को संदर्भित करता है ।

इस उदाहरण को इसे समझाना चाहिए:

public class LocalScreen {
    
    public void method() {
        
        new Runnable() {
            public void run() {
                // Prints "An anonymous Runnable"
                System.out.println(this.toString());
                
                // Prints "A LocalScreen object"
                System.out.println(LocalScreen.this.toString());
                
                // Won't compile! 'this' is a Runnable!
                onMake(this);
                
                // Compiles! Refers to enclosing object
                onMake(LocalScreen.this);
            }
            
            public String toString() {
                return "An anonymous Runnable!";
            }
        }.run();
    }
    
    public String toString() { return "A LocalScreen object";  }
    
    public void onMake(LocalScreen ls) { /* ... */ }
    
    public static void main(String[] args) {
        new LocalScreen().method();
    }
}

आउटपुट:

An anonymous Runnable!
A LocalScreen object

इस पोस्ट को यहाँ एक लेख के रूप में फिर से लिखा गया है


क्या होगा अगर आपके पास कुछ है: public class a { private class a { public void run() { System.out.println(a.this.toString()); } } मैं मान रहा हूं कि यह वही मामला है; a.thisभीतर run()का उल्लेख करना चाहिए संलग्नित a 'एस this। क्या मैं सही हू? (OSX किंडल प्रीव्यूअर ऐप की .jarफ़ाइलों में यह मिनिमाइज्ड कोड कैसे है , मैं सिर्फ यह समझने की कोशिश कर रहा हूं कि मैं क्या देख रहा हूं।)
मैट Mc

जावा में एक आंतरिक वर्ग का नाम उसके किसी भी संलग्नक वर्ग (JLS 8.1) के समान नहीं हो सकता है, इसलिए a.thisआपके उदाहरण में परिभाषित नहीं है। मुझे नहीं पता कि यह बाधा बायटेकोड के लिए सही है या नहीं। शायद नहीं।
aioobe

56

इसका अर्थ है thisबाहरी LocalScreenवर्ग का उदाहरण ।

thisक्वालीफ़ायर के बिना लिखना उस आंतरिक वर्ग का उदाहरण लौटाएगा जो कॉल अंदर है।


4
अभी भी काफी समझ नहीं है। जब मैं इसे "इस" की तुलना में "LocalScreen.this" के रूप में कोड करता हूं तो क्या अंतर है? मैंने दोनों का परीक्षण किया और संकलक ने केवल "LocalScreen.this" को स्वीकार किया। AFuncCall का पहला पैरामीटर aParent वर्ग की अपेक्षा करता है जो "Somethig" का मूल वर्ग है।
जॉनी जैज

1
मैं इस बारे में भी उत्सुक हूं। क्या आप इसका कोई मतलब बता सकते हैं? मैं उपरोक्त कोड में परिभाषित किसी भी आंतरिक वर्गों को नहीं देखता हूं; क्या प्रत्येक जावा फंक्शन में एक संबद्ध अनाम वर्ग होता है, जिसका वह सदस्य होता है?
पाउंडिफ़डे

4
@ क्राचर: उपयोग में आंतरिक वर्ग हैं; ओपी ने उन्हें कोड स्निपेट में शामिल नहीं किया। यह सिंटैक्स केवल एक गैर-स्थिर आंतरिक वर्ग में समर्थित है।
एसएलएसी

अच्छा है कि आपने आधिकारिक जावा प्रलेखन के लिए एक लिंक प्रदान किया है।
क्रिज़ीस्तोफ़ टोमाज़वेस्की

14

संकलक कोड लेता है और इसके साथ कुछ ऐसा करता है:

public class LocalScreen 
{
    public void method() 
    {
        new LocalScreen$1(this).run;
    }

    public String toString() 
    {
        return "A LocalScreen object"; 
    }

    public void onMake(LocalScreen ls) { /* ... */ }

    public static void main(String[] args) 
    {
        new LocalScreen().method();
    }
}

class LocalScreen$1
     extends Runnable
{
    final LocalScreen $this;

    LocalScreen$1(LocalScreen $this)
    {
        this.$this = $this;
    }

    public void run() 
    {
        // Prints "An anonymous Runnable"
        System.out.println(this.toString());

        // Prints "A LocalScreen object"
        System.out.println($this.toString());

        // Won't compile! 'this' is a Runnable!
        //onMake(this);

        // Compiles! Refers to enclosing object
        $this.onMake($this);
    }

    public String toString() 
    {
        return "An anonymous Runnable!";
    }
}

जैसा कि आप देख सकते हैं, जब कंपाइलर एक आंतरिक वर्ग लेता है तो इसे एक बाहरी वर्ग में परिवर्तित कर देता है (यह एक डिज़ाइन निर्णय था जो एक लंबे समय पहले किया गया था ताकि वीएम को आंतरिक कक्षाओं को समझने के लिए बदलने की आवश्यकता न हो)।

जब एक गैर-स्थिर आंतरिक वर्ग बनाया जाता है, तो उसे माता-पिता के संदर्भ की आवश्यकता होती है ताकि वह बाहरी वर्ग के तरीकों / पहुंच चर को कॉल कर सके।

यह जो भीतर का वर्ग था, वह उचित प्रकार नहीं है, आपको ऑनमेक विधि को कॉल करने के लिए सही प्रकार प्राप्त करने के लिए बाहरी वर्ग तक पहुंच प्राप्त करने की आवश्यकता है।


नहीं new LocalScreen$1().run;होना चाहिए new LocalScreen$1(this).run;?
डिस्कूटेंट

यह प्रश्न का एक रेखांकित उत्तर है। दिलचस्प सामान।
पिंकर्टन

12

Class.thisबाहरी वर्ग के उदाहरण तक पहुँच की अनुमति देता है। निम्न उदाहरण देखें।

public class A
{
  final String name;
  final B      b;
  A(String name) {
    this.name = name;
    this.b = new B(name + "-b");
  }

  class B
  {
    final String name;
    final C      c;
    B(String name) {
      this.name = name;
      this.c = new C(name + "-c");
    }

    class C
    {
      final String name;
      final D      d;
      C(String name) {
        this.name = name;
        this.d = new D(name + "-d");
      }

      class D
      {
        final String name;
        D(String name) {
          this.name = name;
        }

        void printMe()
        {
          System.out.println("D: " + D.this.name); // `this` of class D
          System.out.println("C: " + C.this.name); // `this` of class C
          System.out.println("B: " + B.this.name); // `this` of class B
          System.out.println("A: " + A.this.name); // `this` of class A
        }
      }
    }
  }
  static public void main(String ... args)
  {
    final A a = new A("a");
    a.b.c.d.printMe();
  }
}

तब आपको मिलेगा।

D: a-b-c-d
C: a-b-c
B: a-b
A: a

अब तक का एकमात्र अच्छी तरह से समझाया गया उत्तर ... यह वास्तव में "Class.this बाहरी वर्ग की आवृत्ति तक पहुँचने की अनुमति देता है" और "Class.this जैसी चीजों को बाहरी वर्ग के इस तक पहुँचने की अनुमति देता है" नहीं। एक वर्ग के पास कोई "यह" नहीं है, केवल उदाहरणों में खुद को संदर्भित करने के लिए है ...
adabojad

-2

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

class THIS {
  def andthen = {
    new THIS {
      println(THIS.this.## + ":inner-THIS.this.##")
      println(this.## + ":inner-this.##")
      new THIS {
        println(THIS.this.## + ":inner-inner-THIS.this.##")
        println(this.## + ":inner-this.##")
      }
    }
  }
  def getInfo = {
    println(THIS.this.## + ":THIS.this.##")
    println(this.## + ":this.##")
  }
}

आप हैशकोड द्वारा (और। ##) के बीच THIS.thisऔर thisनए THIS ऑपरेशन में अंतर देख सकते हैं

स्केला कंसोल में परीक्षण:

scala> val x = new THIS
x: THIS = THIS@5ab9b447

scala> val y = x.andthen
1522119751:inner-THIS.this.##
404586280:inner-this.##
1522119751:inner-inner-THIS.this.##
2027227708:inner-this.##
y: THIS = THIS$$anon$1@181d7f28

scala> x.getInfo
1522119751:THIS.this.##
1522119751:this.##

THIS.thisहमेशा बाहरी THIS वर्ग की ओर इशारा करते हैं, जो कि वैल x द्वारा संदर्भित होता है, लेकिन thisअनाम नए ऑपरेशन से परे है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.