2009-06-17 18 views
27

जब हम वस्तुओं को क्रमबद्ध करते हैं, स्थिर सदस्यों को क्रमबद्ध नहीं किया जाता है, लेकिन अगर हमें ऐसा करने की ज़रूरत है, तो क्या कोई रास्ता है?जावा क्लास के स्थिर डेटा सदस्यों को क्रमबद्ध कैसे करें?

+18

डेटा के लिए स्थिर सदस्यों को बताया कि धारावाहिक की जानी चाहिए का उपयोग कर बंद करो? – krosenvold

+7

अनुपूरक: म्यूटेबल राज्य को पकड़ने के लिए स्थिर सदस्यों का उपयोग करना बंद करें। – Juliet

+0

+1, यदि आप क्रमबद्ध करते हैं, तो स्थिर सदस्यों का उपयोग न करें – marcgg

उत्तर

18

पहला सवाल यह है कि आपको स्थिर सदस्यों को क्रमबद्ध करने की आवश्यकता क्यों है?

स्टेटिक सदस्य वर्ग के साथ जुड़े हुए हैं, उदाहरणों से नहीं, इसलिए उदाहरण को क्रमबद्ध करते समय उन्हें शामिल करना समझ में नहीं आता है।

पहला समाधान उन सदस्यों को स्थिर नहीं बनाना है। या, यदि वे सदस्य मूल वर्ग और लक्ष्य वर्ग (समान वर्ग, लेकिन संभवतः विभिन्न रनटाइम वातावरण) में समान हैं, तो उन्हें बिल्कुल क्रमबद्ध न करें।

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

+2

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

+4

क्या आपको उस नंबर को सीधे स्टोर करने की आवश्यकता है? यदि आप संख्या को अपडेट करते हैं क्योंकि आप प्रत्येक कार को deserialize (readObject ओवरराइड करके) यह serialization में कारों की संख्या को सही ढंग से प्रतिबिंबित करेगा। –

+0

स्टेटिक चर क्लास की ऑब्जेक्ट्स (साझा मेमोरी) के सभी उदाहरणों के बीच साझा किया जाता है। यदि आपको कुछ स्थैतिक बचाने की आवश्यकता है, जैसे कि आपके पास अलग-अलग मानों का एक enum था और समय-समय पर आप उस enum प्रकार के स्थिर मान को बदल देंगे, सहेजे गए मान को बदलना उतना आसान हो सकता है जितना कि सभी वर्ग स्थानीय चर सेट करते हैं उस प्रकार के लिए।या आप इसे एक कदम आगे ले जा सकते हैं, और कक्षाओं का एक गुच्छा वर्ग वर्ग का विस्तार कर सकते हैं, और कक्षा जो कुछ भी अपने स्थानीय बच्चों को स्थानीय चर साझा कर सकती है। जब आप deserialize करते हैं तो आप अपने स्थिर मूल्यों को फिर से लोड कर सकते हैं कि वे कैसे थे। –

2

स्टेटिक सदस्य कक्षा से संबंधित हैं, व्यक्तिगत वस्तुओं के लिए नहीं।

आपको अपनी डेटा संरचना पर पुनर्विचार करना चाहिए।

5

आप को लागू करने से क्रमबद्धता को नियंत्रित कर सकते हैं:

private void writeObject(ObjectOutputStream out) throws IOException; 

private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException; 

क्रमबद्धता http://java.sun.com/developer/technicalArticles/Programming/serialization/ का पूरा विवरण नहीं है।

जैसा कि अन्य उत्तरों ने कहा है, यह वास्तव में स्थिरता को क्रमबद्ध करने के लिए समझ में नहीं आता है क्योंकि यह वह वस्तु नहीं है जिसे आप धारावाहिक कर रहे हैं और ऐसा करने की ज़रूरत नहीं है जैसे आपको मेरे कोड के साथ अन्य समस्याएं मिलती हैं।

+0

आप क्रमबद्धता को नियंत्रित कर सकते हैं, लेकिन स्थिर डेटा डालने के लिए कहीं भी समझदारी नहीं है क्योंकि यह संदर्भ में कोई समझ नहीं लेता है। –

+0

चूंकि हम संदर्भ को नहीं जानते हैं, इसलिए हम यह नहीं कह सकते कि यह समझ में आता है या नहीं। उदाहरण के लिए, डिफ़ॉल्ट क्रमिकरण का उपयोग करने के बाद, स्थिर सदस्य को स्ट्रीम में जोड़ने का अर्थ हो सकता है। Deserialization पर, कोई स्थिर सदस्य सेट कर सकते हैं अगर यह शून्य है, अन्यथा serialized वस्तु को त्यागें। – erickson

+0

टॉम, आप "पुनरावृत्ति द्वारा सबूत" का दुरुपयोग कर रहे हैं, है ना? ;) –

2

अच्छे उत्तर और टिप्पणियां - ऐसा मत करें। पर कैसे?

संभावना है कि आप अपने सभी "स्टेटिक्स" को पकड़ने के लिए ऑब्जेक्ट बनाने से सबसे अच्छे होंगे। उस ऑब्जेक्ट में शायद आपकी कक्षा से भी कोई स्थिर विधि होनी चाहिए।

आपकी कक्षा का प्रत्येक उदाहरण इस अन्य वर्ग को पकड़ सकता है - या यदि आपको वास्तव में यह करना है कि आप इसे एक सिंगलटन बना सकते हैं जिसे कोई भी सदस्य एक्सेस कर सकता है।

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

आपको शायद यह पता चलेगा कि यह समाधान अन्य सीरियलाइजेशन समस्याओं को भी हल करता है जिन्हें आपने अभी तक नहीं देखा था।

14

लोग, स्थैतिक का मतलब IMMUTABLE नहीं है। उदाहरण के लिए, मैं JVM और/या होस्ट कंप्यूटर को पुनरारंभ करने के बाद बाद में फिर से शुरू करने के लिए गणना के पूरे राज्य को क्रमबद्ध करना चाहता हूं (हां, स्थिर फ़ील्ड - काउंटर आदि)।

जैसा कि पहले से कहा गया है, इसका सही उत्तर बाहरी, उपयोग नहीं करने योग्य, इंटरफ़ेस का उपयोग करना है। फिर आपके पास पूर्ण नियंत्रण है कि आप किस प्रकार और कैसे बाहरी हैं।

+1

यदि गणना की स्थिति उस ऑब्जेक्ट में एम्बेड नहीं की गई है जिसे आप क्रमबद्ध कर रहे हैं तो आपको उस ऑब्जेक्ट के क्रमिकरण के हिस्से के रूप में इसे संग्रहीत नहीं किया जाना चाहिए। – DJClayworth

+3

उत्परिवर्तनीय स्थिर आमतौर पर टूटा हुआ मतलब है। –

+1

फिर से सोचें। उदाहरण के लिए, बहुप्रचारित जेनेटिक एल्गोरिदम के बारे में कैसे? मूल्यांकन किए गए (स्थिर) भंडारण का मूल्यांकन मूल्यांकन प्रकारों की रजिस्ट्री को रखने के लिए किया जाता है। इसे एक सिंगलटन बनाओ? संभव है, लेकिन इसकी खुद की कमी है। –

0

हां, हम स्थैतिक चर को क्रमबद्ध कर सकते हैं। लेकिन हम अपना खुद का writeObject() और readObject() लिख सकते हैं। मुझे लगता है कि यह समस्या को हल कर सकता है।

0

कॉम्पैक्ट कार्यान्वयन के लिए, अपने वर्ग कॉल में readObject & writeObject लागू उन तरीकों जो सामान्य क्रमबद्धता संभालती भीतर & defaultWriteObject तरीकों defaultReadObject और फिर serializing & de-serializing जो कुछ अतिरिक्त फ़ील्ड आप की जरूरत के साथ आगे बढ़ना।

सादर, जीके

5

यह स्थिर क्षेत्र के लिए क्रमबद्धता है: newBookingNumber।

class Booking implements Serializable 
{ 

    /** 
    * Generated serial version ID. 
    */ 

    private static final long serialVersionUID = 5316748056989930874L; 

    // To hold new booking number. 
    private static int newBookingNumber = 0; 

    // The booking number. 
    private int bookingNumber; 


    /* 
    * Default serializable fields of a class are defined to be 
    * the non-transient and non-static fields. So, we have to 
    * write and read the static field separately. 
    */ 
    private void writeObject(ObjectOutputStream oos) 
     throws IOException 
    { 
     oos.defaultWriteObject(); 
     oos.writeObject(new Integer(newBookingNumber)); 
    } 

    private void readObject(ObjectInputStream ois) 
    throws ClassNotFoundException, IOException 
    { 
     ois.defaultReadObject(); 
     newBookingNumber = (Integer)ois.readObject(); 
    } 
} 
2

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

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

पहेली का दूसरा भाग लागू() प्रकार का फ़ंक्शन है। यह मैपिंग के माध्यम से जाता है, और यह स्थिर वर्ग के लिए क्या कर सकता है लागू होता है।

आपको यह भी सुनिश्चित करना होगा कि स्थिर सदस्यों की सामग्री स्वयं क्रमबद्ध हो।

जैसा कि उम्मीद है कि इस उदाहरण वर्ग से देखा जा सकता है, स्थिर सदस्यों को आसानी से बचाया जा सकता है और लौटाया जा सकता है। कक्षाओं, सुरक्षा उपायों आदि के यूआईडी के बारे में चिंता करने के लिए मैं इसे कार्यान्वयनकर्ता के पास छोड़ दूंगा। एसएएसएएस() इकाई परीक्षण के लिए उपयोग किया जाता है। ऐपसेटिंग वह कक्षा है जिसमें सभी स्थिर फ़ील्ड शामिल हैं जिन्हें आप क्रमबद्ध करना चाहते हैं।

public class AppSettingsReflectorSaver implements Serializable { 

HashMap<String, Object> genericNamesAndContents = new HashMap<String, Object>(); 
private AppSettingsReflectorSaver() { 
} 

static AppSettingsReflectorSaver createAppSettingsSaver() { 
    AppSettingsReflectorSaver ret = new AppSettingsReflectorSaver(); 
    ret.copyAppSettings(); 
    return ret; 
} 

private void copyAppSettings() { 
    Field[] fields = AppSettings.class.getFields(); 
    for (Field field : fields) { 
     mapContentsForSerialization(field); 
    } 
} 

private void mapContentsForSerialization(Field field) { 
    try { 
     Object fieldContents = field.get(AppSettings.class); 
     genericNamesAndContents.put(field.toGenericString(), fieldContents); 
    } catch (IllegalArgumentException ex) { 
     Logger.getLogger(AppSettingsReflectorSaver.class.getName()).log(Level.SEVERE, null, ex); 
    } catch (IllegalAccessException ex) { 
     Logger.getLogger(AppSettingsReflectorSaver.class.getName()).log(Level.SEVERE, null, ex); 
    } 
} 

boolean isSameAs(AppSettingsReflectorSaver now) { 
    for(String thisKey : genericNamesAndContents.keySet()){ 
     boolean otherHasThisKey = now.genericNamesAndContents.containsKey(thisKey); 
     Object thisObject = genericNamesAndContents.get(thisKey); 
     Object otherObject = now.genericNamesAndContents.get(thisKey); 
     boolean otherHasThisValue = thisObject.equals(otherObject); 
     if (!otherHasThisKey || !otherHasThisValue){ 
      return false; 
     } 
    } 
    return true; 
} 

void applySavedSettingsToStatic() { 
    Field[] fields = AppSettings.class.getFields(); 
    for (Field field : fields) { 
     if (!genericNamesAndContents.containsKey(field.toGenericString())){ 
      continue; 
     } 
     Object content = genericNamesAndContents.get(field.toGenericString()); 
     try { 
      field.set(AppSettings.class, content); 
     } catch (IllegalArgumentException ex) { 
      Logger.getLogger(AppSettingsReflectorSaver.class.getName()).log(Level.SEVERE, null, ex); 
     } catch (IllegalAccessException ex) { 
      Logger.getLogger(AppSettingsReflectorSaver.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 
} 

}

यह मेरी पहली पोस्ट है - मुझ पर आसान जाना: पी ~

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