2011-04-03 8 views
92

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

public class LocalScreen { 

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

क्या aFuncCall में LocalScreen.this साधन करता है?

उत्तर

48

इसका मतलब है this बाहरी LocalScreen कक्षा का उदाहरण।

योग्यता के बिना this लिखने से inner class का उदाहरण वापस आएगा कि कॉल अंदर है।

+4

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

+3

आपको आंतरिक कक्षाओं के बारे में जानने की जरूरत है। – SLaks

+1

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

141

LocalScreen.this संलग्न कक्षा के this को संदर्भित करता है।

यह उदाहरण यह व्याख्या करनी चाहिए:

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 

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

+2

Thnx ... शानदार उदाहरण .... सरल, nd सीधे 2 डी बिंदु –

+0

क्या होगा यदि आपके पास कुछ ऐसा है: 'सार्वजनिक वर्ग एक {निजी वर्ग एक {सार्वजनिक शून्य दौड़() {System.out.println (a.this ।तार()); }} 'मुझे लगता है कि यह वही मामला है; 'रन') के भीतर 'a.this' को * संलग्न *' a' ''' का संदर्भ लेना चाहिए। क्या मैं सही हू? (इस प्रकार ओएसएक्स किंडल पूर्वावलोकनकर्ता ऐप की '.jar' फाइलों में छोटा कोड है, मैं बस यह समझने की कोशिश कर रहा हूं कि मैं क्या देख रहा हूं।) –

+0

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

11

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
+0

अभी तक एकमात्र अच्छी तरह से समझाया गया उत्तर ... यह वास्तव में "कक्षा है। यह बाहरी वर्ग के उदाहरण तक पहुंच की इजाजत देता है" और "कक्षाओं" जैसी चीजों को बाहरी वर्ग तक पहुंच की अनुमति नहीं देता है। किसी वर्ग में कोई "यह" नहीं होता है, केवल उदाहरणों को संदर्भित करने के लिए केवल उदाहरण हैं ... –

13

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

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!"; 
    } 
} 

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

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

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

+0

'नया लोकलस्क्रीन $ 1() रन नहीं होना चाहिए; 'नया लोकलस्क्रीन $ 1 (यह) .run;'? – Diskutant

+0

फिक्स्ड। धन्यवाद!! – TofuBeer

+0

यह प्रश्न का एक अंडररेड उत्तर है। दिलचस्प सामान। – BrettG

-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 इस ऑपरेशन के बीच अंतर देख सकते हैं hashCode द्वारा

परीक्षण (##।):

scala> val x = new THIS 
x: THIS = [email protected] 

scala> val y = x.andthen 
1522119751:inner-THIS.this.## 
404586280:inner-this.## 
1522119751:inner-inner-THIS.this.## 
2027227708:inner-this.## 
y: THIS = [email protected] 

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

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

संबंधित मुद्दे