सवाल कन्स्ट्रक्टर में एक स्थिर अंतिम क्षेत्र शुरू करें


public class A 
{    
    private static final int x;

    public A() 
    {
        x = 5;
    }
}
  • final इसका मतलब है कि चर केवल एक बार (कन्स्ट्रक्टर में) असाइन किया जा सकता है।
  • static इसका मतलब है कि यह एक वर्ग उदाहरण है।

मैं नहीं देख सकता कि यह क्यों प्रतिबंधित है। वे कीवर्ड एक दूसरे के साथ हस्तक्षेप करते हैं?


76
2018-02-23 16:28


मूल




जवाब:


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

class A {    
    private static final int x;

    static {
        x = 5;
    }
}

लेकिन, यदि आप स्थैतिक को हटाते हैं, तो आपको यह करने की अनुमति है:

class A {    
    private final int x;

    public A() {
        x = 5;
    }
}

या यह:

class A {    
    private final int x;

    {
        x = 5;
    }
}

162
2018-02-23 16:32



स्पष्ट और सरल उत्तर के लिए +1 - sactiw
स्पष्ट रूप से कोई भी यह समझाने के लिए परेशान नहीं है कि स्थिर चर वेरिएबल्स हैं जो कक्षा के सभी उदाहरणों में मौजूद हैं। इस प्रकार, उन्हें केवल तभी तत्काल किया जा सकता है जब कक्षा लोड हो जाती है - जब कक्षा के संभावित रूप से कई उदाहरण नहीं बनाए जाते हैं। - iheanyi
इसके अलावा, मैं केवल एक स्थिर ब्लॉक की बजाय घोषणा में असाइन करने की सिफारिश करता हूं। यह सिर्फ क्लीनर है और शायद ओपी क्या करना चाहता था: private static final int x = 5; - qwertzguy


क्लास लोड होने पर स्थिर अंतिम चर प्रारंभ किए जाते हैं। कन्स्ट्रक्टर को बाद में कहा जा सकता है, या बिल्कुल नहीं। साथ ही, कन्स्ट्रक्टर को कई बार (प्रत्येक नई वस्तु के साथ) कहा जाएगा, इसलिए फ़ील्ड अब अंतिम नहीं हो सकता है।

यदि आपको अपने स्थिर अंतिम फ़ील्ड को प्रारंभ करने के लिए कस्टम तर्क की आवश्यकता है, तो उसे स्थिर ब्लॉक में रखें


15
2018-02-23 16:31



ठीक है, लेकिन आपने अभी समझाया कि क्या हो रहा है। मैं पूछ रहा हूँ क्यों? मेरा मतलब है, फाइनल के बिना यह काम करता है, स्थिर के बिना यह काम करता है। तो दोनों संयोजन कुछ नए तर्क बनाता है? - Yaron Levi
@YaronLevi उन्होंने अभी यह कहा ... स्थिर क्षेत्र वर्ग का सदस्य है। आपके कन्स्ट्रक्टर में आप चर के लिए एक मान असाइन कर रहे हैं। अंतिम शब्द का अर्थ है कि आप केवल एक बार वैरिएबल को एक मान असाइन कर सकते हैं, आपके कोड में आप प्रत्येक बार क्लास को तत्काल होने पर चर के लिए मान निर्दिष्ट कर रहे हैं - क्योंकि चर स्थिर है (वर्ग का सदस्य)। यदि आप स्थैतिक से छुटकारा पा लेते हैं, तो आप इसे प्रत्येक बार एक नया चर के बाद से निर्माता में एक मान असाइन कर सकते हैं। यदि आप फाइनल से छुटकारा पा लेते हैं तो यह केवल एक स्थिर चर है, जिसे आप किसी भी समय एक नया मान असाइन कर सकते हैं। - user12345613
@ user12345613 ने एक बहुत अच्छा स्पष्टीकरण दिया। अकेले, या तो अंतिम या स्थैतिक काम; लेकिन एक बार एक साथ रखा गया, "स्थिर अंतिम" बलों सभी वर्गों में उस वर्ग के लिए केवल एक ऐसा क्षेत्र है और केवल कितने उदाहरणों पर ध्यान दिए बिना इसे आरंभ किया जा सकता है। - user908645


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

जब आप इसे घोषित करते हैं तो आपको मूल्य निर्धारित करना चाहिए

private static final x=5;

यदि आपको अतिरिक्त तर्क, या अधिक जटिल तत्काल आवश्यकता है, तो यह एक स्थिर प्रारंभकर्ता ब्लॉक में किया जा सकता है।


6
2018-02-23 16:32





static इसका मतलब है कि चर पर आवेदन वैरिएबल अद्वितीय है। final इसका मतलब है कि इसे केवल एक बार सेट किया जाना चाहिए।

यदि आप इसे अपने कन्स्ट्रक्टर में सेट करते हैं, तो आप चर को एक से अधिक बार सेट करने की अनुमति देते हैं।

इसलिए आपको इसे सीधे शुरू करना चाहिए या इसे प्रारंभ करने के लिए एक स्थिर विधि का प्रस्ताव देना चाहिए।


5
2018-02-23 16:33





अंतिम इसका मतलब यह नहीं है कि इसे कन्स्ट्रक्टर में शुरू किया जाना है। आम तौर पर यह किया जाता है:

 private static final int x = 5;

स्थिर इसके बजाय इसका मतलब है कि चर के वर्ग के कई उदाहरणों के माध्यम से साझा किया जाएगा। उदाहरण के लिए :

public class Car {
   static String name;
   public Car(String name) {
      this.name = name;
   }
}

...

Car a = new Car("Volkswagen");
System.out.println(a.name); // Produces Volkswagen

Car b = new Car("Mercedes");
System.out.println(b.name); // Produces Mercedes
System.out.println(a.name); // Produces Mercedes

3
2018-02-23 16:38





इसके बारे में सोचो। आप इसे अपने कोड से कर सकते हैं:

A a = new A();
A b = new A(); // Wrong... x is already initialised

एक्स शुरू करने के सही तरीके हैं:

public class A 
{    
    private static final int x = 5;
}

या

public class A 
{    
    private static final int x;

    static
    {
        x = 5;
    }
}

2
2018-02-23 16:33





    public class StaticFinalExample {
  /*
   * Static final fields should be initialized either in
   * static blocks or at the time of declaration only
   * Reason : They variables are like the utility fields which should be accessible
   * before object creation only once.
   */
  static final int x;

  /*
   * Final variables shuould be initialized either at the time of declaration or
   * in initialization block or constructor only as they are not accessible in static block
   */
  final int y;

  /*
   * Static variables can be initialized either at the time of declaration or
   * in initialization or constructor or static block. Since the default value is given to the
   * static variables by compiler, so it depends on when you need the value
   * depending on that you can initialize the variable appropriately
   * An example of this is shown below in the main method
   */
  static int z;

  static {
    x = 20; // Correct
  }
  {
    y = 40; // Correct
  }
  StaticFinalExample() {
    z = 50; // Correct
  }
  public static void main (String args[]) {
    System.out.println("Before Initialization in Constructor" + z);   // It will print 0
    System.out.println("After Initializtion in Constructor" + new StaticFinalExample().z); // It will print 50
  }
}

0
2018-04-05 10:59