2016-10-11 6 views
10

मैं आज अज्ञात वर्गों के साथ प्रयोग कर रहा था। जब मैं System.out.println(super.x); करता हूं, तो यह 12 प्रिंट करता है, और जब मैं System.out.println(x); का उपयोग करता हूं तो यह 4 प्रिंट करता है। मैंने सोचा कि super.x 4 प्रिंट करेगा और सोच रहा था कि कोई मुझे बता सकता है कि यह क्यों है?बेनामी क्लास चर

public class AnonClass { 

    private int x = 1; 

    public AnonClass(int x) { 
     this.x = x; 
    } 

    public static void main(String[] args) { 
     AnonClass test = new AnonClass(4); 
     test.testMethod(); 
    } 

    public void testMethod() { 

     AnonClass anon = new AnonClass(12) { 
      { 
       System.out.println(super.x); //Prints 12 
       System.out.println(x); //prints 4 
      } 
     }; 

    } 
} 
+0

मैंने सोचा था कि 'super' केवल विरासत के साथ इस्तेमाल किया गया था। मुझे नहीं लगता। – Gendarme

+2

@ गेंडर्म आप ऐसा क्यों मानते हैं? अज्ञात कक्षाएं उनके द्वारा विस्तारित कक्षा से प्राप्त होती हैं। –

+0

@ एंडी टर्नर ठीक है, मुझे लगता है कि जावा में मेरा ज्ञान भी है ... उथला। यह पूरी बात मेरे बाहर है। – Gendarme

उत्तर

11

जब आप class AnonClass अंदर इस तरह एक गुमनाम वर्ग को परिभाषित:

AnonClass anon = 
    new AnonClass(12) { 
     { 
     System.out.println(super.x); //Prints 12 
     System.out.println(x); //prints 4 
     } 
    }; 

संकलक इस तरह एक वर्ग कुछ पैदा करेगा:

class AnonClass$1 extends AnonClass { 
    final AnonClass enclosed; 

    AnonClass$1(AnonClass enclosed, int x) { 
    super(x); 
    System.out.println(super.x); 
    System.out.println(enclosed.x); 
    this.enclosed = enclosed; 
    } 
} 

और फिर आह्वान इसे पसंद:

AnonClass anon = new AnonClass$1(this, 12); 

ध्यान दें कि superconstructor (super(x);) का आविष्कार उदाहरण प्रारंभकर्ता (System.out.println लाइनों) की सामग्री से पहले होता है।

इस प्रकार, क्षेत्र AnonClass.x सुपरकोनस्ट्रक्टर द्वारा 12 तक शुरू किया गया है, और उसके बाद के माध्यम से इसका मान 12 के रूप में मुद्रित किया गया है।

फिर, System.out.println(x) वास्तव में AnonClass की enclosing उदाहरण है, जिसका मूल्य 4.

कारण है उसे वापस 12 प्रिंट यह नहीं है कि xprivate है है में x संदर्भित कर रहा है; और जैसा कि यह JLS Sec 8.2 में कहा गया है:

निजी घोषित कक्षा के सदस्य उस वर्ग के उप-वर्गों द्वारा विरासत में नहीं हैं।

तो प्रिंट करने के लिए AnonClass$1.x नहीं है; x नामक दायरे में एकमात्र पहचानकर्ता AnonClass.x है।

+1

जावा विनिर्देश का कौन सा हिस्सा कहता है कि अज्ञात वर्ग में एक अयोग्य पहचानकर्ता संलग्न वर्ग को हल करता है, न कि अज्ञात सुपर क्लास? मैं एक "संदिग्ध" संकलन त्रुटि की उम्मीद की होगी। – Andreas

+0

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

+2

मेरे प्रश्न का उत्तर देने का संकेत यहां है, मुझे लगता है: यदि आप फ़ील्ड 'x' से 'निजी' को हटाते हैं, तो 'super.x' और' x' दोनों सुपर इंस्टेंस को संदर्भित करते हैं। केवल तभी जब 'x' 'निजी' अयोग्य' x' संलग्न उदाहरण को संदर्भित करेगा। – Andreas

1

आप दो वर्गों यहाँ हैं: नियमित रूप से वर्ग AnonClass और अनाम वर्ग AnonClass$1AnonClass

का विस्तार इन दोनों वर्गों है x क्षेत्र

तुम भी दो वस्तुओं है: प्रकार AnonClass में से एक x = 4 और साथ main विधि के अंदर instantiated x = 12

साथ प्रकार AnonClass$1testMethod() अंदर instantiated के दूसरे एक जब आप super.x के मान को प्रिंट कर रहे हैं तो आप दूसरे ऑब्जेक्ट के x फ़ील्ड तक पहुंच रहे हैं; लेकिन x का मूल्य पहली वस्तु के अंतर्गत आता है क्योंकि आप वर्ग static नहीं है और बाहरी वर्ग के उदाहरण

संदर्भ के लिए एक अंतर्निहित संदर्भ शामिल हैं: Nested Classes in Java

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