2014-11-06 11 views
5

की स्थिर अंतिम क्षेत्र के लिए एक उदाहरण के क्षेत्र और एक ही नाम के एक स्थानीय चर हम उपसर्ग this. के साथ क्षेत्र के लिए उपयोग प्राप्त करने के साथ बीच अंतर के लिए वर्ग के नाम के साथ पहुँच योग्यता से एक स्थिर संदर्भ में एक ही बात:असाइन एक ही नाम

import java.util.*; 

class Test { 
    public static final Map<String,Object> map; 

    static { 
     Map<String,Object> map = new HashMap<>(); 

     // ... 
     // assume I fill the map with useful data here 
     // ... 

     // now I want to freeze it and assign it to the field 
     Test.map = Collections.unmodifiableMap(map); 
    } 
} 

संकलक इस कोड के साथ कोई लेना देना नहीं चाहता है। मेरे पास इस तरह के कई चर हैं और उनमें से सभी के लिए यह चिल्लाना जारी रखता है: "अंतिम चर के लिए मान असाइन नहीं कर सकता"। यदि मैं इसे असाइन नहीं करता हूं, तो यह इसके बजाय "वैरिएबल प्रारंभ नहीं किया गया" शिकायत करता है। अगर मैं शुरुआत में स्थैतिक क्षेत्र को आवंटित करता हूं और नक्शे को बाद में अप्रचलित बनाने की कोशिश करता हूं, तो यह शिकायत करता है कि "चर पहले ही असाइन किया जा सकता है"। यह किसी भी चीज़ से खुश नहीं है।

क्या यह भाषा में एक दोष है, या संकलक में एक बग है? कंपाइलर को इसके रूप में करने के लिए स्क्वैश करने का सबसे अच्छा तरीका क्या है?

+1

दो अलग-अलग नामों का उपयोग करें। इस बात का कोई कारण नहीं है कि स्थैतिक ब्लॉक के अंदर 'मानचित्र' को स्थिर 'मानचित्र' फ़ील्ड के समान नाम होना चाहिए। – ajb

+0

नामकरण काम करता है, लेकिन यह बदसूरत है, क्योंकि मैं प्रारंभकर्ता ब्लॉक में कई बार चर का उपयोग करता हूं, और वे उनके उचित नामों के साथ अधिक सार्थक होंगे। मैं सोच रहा था कि क्या कुछ बेहतर था। – Boann

उत्तर

5

हल करने के लिए सबसे आसान तरीका है इस प्रकार है:

import java.util.*; 

class Test { 
    public static final Map<String,Object> map; 

    static { 
     Map<String,Object> contents = new HashMap<>(); 

     map = Collections.unmodifiableMap(contents); 
    } 
} 

किसी तरह ऐसा लगता है कि अगर आप जावा 8 में वर्ग के नाम के साथ लगातार चुने जाते हैं, संकलक यह नहीं होगा।

अद्यतन

कुछ और खुदाई करने के बाद, ऐसा लगता है Java Language Specification स्पष्ट रूप से कहा गया है कि इतना आसान (अयोग्य) नाम अंतिम क्षेत्रों (प्रकाश डाला मेरा) का काम के लिए इस्तेमाल किया जाना चाहिए:

स्थानीय चर या रिक्त अंतिम फ़ील्ड x की प्रत्येक पहुंच के लिए, x निश्चित रूप से पहुंच से पहले असाइन किया जाना चाहिए, या संकलन-समय त्रुटि उत्पन्न होती है।

इसी प्रकार, प्रत्येक रिक्त अंतिम चर को सबसे अधिक बार असाइन किया जाना चाहिए; जब इसे असाइनमेंट होता है तो इसे निश्चित रूप से असाइन किया जाना चाहिए।

इस तरह के एक काम होने के लिये परिभाषित किया गया है यदि और केवल यदि या तो चर का सरल नाम (या एक क्षेत्र के लिए, अपने सरल नाम इस के योग्य) एक काम ऑपरेटर के बाएं हाथ की ओर होता है

+1

जेएलएस में इसे ट्रैक करने के लिए धन्यवाद। – ajb

1

ऐसा लगता है कि यह कहना

public static final <something> x; 
static { 
    x = <whatever>; 
} 

नहीं बल्कि

public static final <something> x; 
static { 
    MyClass.x = <whatever>; 
} 

मुझे यकीन है कि नहीं कर रहा हूँ क्यों काम करता है, लेकिन यह है कि व्यवहार मैं हो रही है। अपने उदाहरण में इसे टालने के लिए, बस Test.map से map बदलें, और अन्य map चर का नाम बदलें।

पीएस रॉबी का जवाब व्यवहार के कारण बताता है।

0

मुझे एक स्थिर ब्लॉक के बजाय क्षेत्र में प्रवेश करने के लिए एक विधि का उपयोग करके एक वर्कअराउंड महसूस हुआ।विधि के अंदर वेरिएबल को निश्चित रूप से नामित किया जा सकता है जिसे वह नामित करना चाहता है:

public static final Map<String,Object> map = initMap(); 

private static Map<String,Object> initMap() { 
    ... 
} 
संबंधित मुद्दे