वास्तव Serializable
में जावा में एक वर्ग होने का क्या मतलब है ? या सामान्य तौर पर, इस मामले के लिए ...
वास्तव Serializable
में जावा में एक वर्ग होने का क्या मतलब है ? या सामान्य तौर पर, इस मामले के लिए ...
जवाबों:
उदाहरण के लिए डिस्क पर सहेजने के लिए सीरियल ऑब्जेक्ट को मेमोरी से बिट्स के एक क्रम तक बना रहा है। Deserialization इसके विपरीत है - डिस्क से हाइड्रेट / ऑब्जेक्ट बनाने के लिए डेटा पढ़ना।
आपके प्रश्न के संदर्भ में, यह एक इंटरफ़ेस है जिसे यदि किसी वर्ग में लागू किया जाता है, तो यह वर्ग अलग-अलग धारावाहिकों द्वारा स्वचालित रूप से क्रमबद्ध और वांछनीय हो सकता है।
हालांकि अधिकांश उपयोगकर्ताओं ने पहले ही जवाब दे दिया है, लेकिन मैं उन लोगों के लिए एक उदाहरण जोड़ना चाहूंगा, जिन्हें विचार समझाने के लिए इसकी आवश्यकता है:
मान लीजिए कि आपके पास निम्न वर्ग का व्यक्ति है:
public class Person implements java.io.Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
public String firstName;
public String lastName;
public int age;
public String address;
public void play() {
System.out.println(String.format(
"If I win, send me the trophy to this address: %s", address));
}
@Override
public String toString() {
return String.format(".....Person......\nFirst Name = %s\nLast Name = %s", firstName, lastName);
}
}
और फिर आप इस तरह एक वस्तु बनाते हैं:
Person william = new Person();
william.firstName = "William";
william.lastName = "Kinaan";
william.age = 26;
william.address = "Lisbon, Portugal";
आप उस धारा को कई धाराओं में क्रमबद्ध कर सकते हैं। मैं दो धाराओं के लिए करूंगा:
मानक उत्पादन के लिए सरलीकरण:
public static void serializeToStandardOutput(Person person)
throws IOException {
OutputStream outStream = System.out;
ObjectOutputStream stdObjectOut = new ObjectOutputStream(outStream);
stdObjectOut.writeObject(person);
stdObjectOut.close();
outStream.close();
}
एक फ़ाइल के लिए सीरियल:
public static void serializeToFile(Person person) throws IOException {
OutputStream outStream = new FileOutputStream("person.ser");
ObjectOutputStream fileObjectOut = new ObjectOutputStream(outStream);
fileObjectOut.writeObject(person);
fileObjectOut.close();
outStream.close();
}
फिर:
फ़ाइल से विवरण:
public static void deserializeFromFile() throws IOException,
ClassNotFoundException {
InputStream inStream = new FileInputStream("person.ser");
ObjectInputStream fileObjectIn = new ObjectInputStream(inStream);
Person person = (Person) fileObjectIn.readObject();
System.out.println(person);
fileObjectIn.close();
inStream.close();
}
इसका अर्थ है कि कक्षा के उदाहरणों को बाइट-स्ट्रीम (उदाहरण के लिए, फ़ाइल में सहेजने के लिए) में बदल दिया जा सकता है और फिर वापस कक्षाओं में बदल दिया जाता है। यह पुनः लोडिंग कार्यक्रम के एक अलग उदाहरण में, या एक अलग मशीन पर भी हो सकता है। सीरियलाइज़ेशन (किसी भी भाषा में) सभी प्रकार के मुद्दों को शामिल करता है, हालांकि, विशेषकर जब आपको क्रमिक एक के अंदर अन्य वस्तुओं का संदर्भ मिला हो।
यहाँ Serialization की एक विस्तृत व्याख्या है : (मेरा अपना ब्लॉग)
क्रमबद्धता:
सीरियलाइज़ेशन एक वस्तु की स्थिति को क्रमबद्ध करने की प्रक्रिया है जिसे बाइट्स के अनुक्रम के रूप में दर्शाया और संग्रहीत किया जाता है। इसे एक फाइल में स्टोर किया जा सकता है। फ़ाइल से ऑब्जेक्ट की स्थिति को पढ़ने और इसे पुनर्स्थापित करने की प्रक्रिया को डीराइजेशन कहा जाता है।
Serialization की क्या आवश्यकता है?
आधुनिक वास्तुकला में, हमेशा वस्तु स्थिति को संग्रहीत करने और फिर उसे पुनः प्राप्त करने की आवश्यकता होती है। हाइबरनेट में उदाहरण के लिए, एक वस्तु को संग्रहीत करने के लिए हमें वर्ग को सीरियल बनाने योग्य बनाना चाहिए। यह क्या करता है, यह है कि एक बार ऑब्जेक्ट राज्य बाइट्स के रूप में सहेजे जाने के बाद इसे किसी अन्य सिस्टम में स्थानांतरित किया जा सकता है जो तब राज्य से पढ़ सकता है और कक्षा को पुनः प्राप्त कर सकता है। ऑब्जेक्ट स्थिति एक डेटाबेस या एक अलग jvm या एक अलग घटक से आ सकती है। Serialization की मदद से हम ऑब्जेक्ट स्टेट को पुनः प्राप्त कर सकते हैं।
कोड उदाहरण और स्पष्टीकरण:
पहले आइए एक नजर डालते हैं आइटम क्लास पर:
public class Item implements Serializable{
/**
* This is the Serializable class
*/
private static final long serialVersionUID = 475918891428093041L;
private Long itemId;
private String itemName;
private transient Double itemCostPrice;
public Item(Long itemId, String itemName, Double itemCostPrice) {
super();
this.itemId = itemId;
this.itemName = itemName;
this.itemCostPrice = itemCostPrice;
}
public Long getItemId() {
return itemId;
}
@Override
public String toString() {
return "Item [itemId=" + itemId + ", itemName=" + itemName + ", itemCostPrice=" + itemCostPrice + "]";
}
public void setItemId(Long itemId) {
this.itemId = itemId;
}
public String getItemName() {
return itemName;
}
public void setItemName(String itemName) {
this.itemName = itemName;
}
public Double getItemCostPrice() {
return itemCostPrice;
}
public void setItemCostPrice(Double itemCostPrice) {
this.itemCostPrice = itemCostPrice;
}
}
उपरोक्त कोड में यह देखा जा सकता है कि आइटम वर्ग सीरियल को लागू करता है ।
यह वह इंटरफ़ेस है जो किसी वर्ग को क्रमबद्ध होने में सक्षम बनाता है।
अब हम देख सकते हैं कि वैरिएबल नामक वैरिएबल UID लॉन्ग वैरिएबल के लिए इनिशियलाइज़ है। इस संख्या की गणना कंपाइलर द्वारा क्लास की स्थिति और क्लास की विशेषताओं के आधार पर की जाती है। यह वह संख्या है जो jvm को किसी ऑब्जेक्ट की स्थिति की पहचान करने में मदद करेगी जब वह फ़ाइल से ऑब्जेक्ट की स्थिति पढ़ती है।
उसके लिए हम आधिकारिक Oracle दस्तावेज पर एक नज़र डाल सकते हैं:
क्रमांकन रनटाइम प्रत्येक क्रमिक श्रेणी के साथ संबद्ध होता है एक संस्करण संख्या, जिसे क्रमबद्धता कहा जाता है, जिसका उपयोग यह प्रमाणित करने के लिए किया जाता है कि क्रमबद्ध वस्तु के प्रेषक और प्रापक ने उस वस्तु के लिए कक्षाएं लोड की हैं जो क्रमांकन के संबंध में संगत हैं। यदि रिसीवर ने ऑब्जेक्ट के लिए एक वर्ग लोड किया है जिसमें संबंधित प्रेषक वर्ग की तुलना में एक अलग serialVersionUID है, तो deserialization एक InvalidClassException में परिणाम देगा। एक क्रमबद्ध वर्ग अपने स्वयं के क्रमबद्ध सीरियल "UID" को स्पष्ट रूप से "serialVersionUID" नाम के एक क्षेत्र की घोषणा करके घोषित कर सकता है जो स्थिर, अंतिम और प्रकार का लंबा होना चाहिए: कोई भी ACCESS-MODIFIER स्थिर अंतिम लंबा धारावाहिक VersionUID = 42L; यदि कोई श्रेणीबद्ध वर्ग स्पष्ट रूप से एक सीरियलवर्जन घोषित नहीं करता है, तब क्रमांकन रनटाइम उस वर्ग के लिए एक डिफ़ॉल्ट serialVersionUID मान की गणना करेगा, जो कक्षा के विभिन्न पहलुओं पर आधारित है, जैसा कि जावा (टीएम) ऑब्जेक्ट सीरियलाइज़ेशन विशिष्टता में वर्णित है। हालाँकि, यह दृढ़ता से अनुशंसा की जाती है कि सभी क्रमिक कक्षाएं स्पष्ट रूप से क्रमबद्धता प्रदान करती हैं, क्योंकि डिफ़ॉल्ट serialVersionUID अभिकलन वर्ग के विवरणों के प्रति अत्यधिक संवेदनशील है जो संकलक कार्यान्वयन के आधार पर भिन्न हो सकते हैं, और इस प्रकार डिसेरिएलाइज़ेशन के दौरान अप्रत्याशित इनवॉयसक्लास अपवाद हो सकते हैं। इसलिए, विभिन्न जावा कंपाइलर कार्यान्वयन के अनुरूप सुसंगत सीरियलवर्जन मूल्य की गारंटी देने के लिए, एक श्रेणीबद्ध श्रेणी को एक स्पष्ट क्रमबद्ध धारावाहिक मूल्य घोषित करना चाहिए। यह भी दृढ़ता से सलाह दी जाती है कि स्पष्ट serialVersionUID घोषणाएं निजी संशोधक का उपयोग करें जहां संभव हो,
यदि आपने देखा है कि एक और खोजशब्द है जिसका हमने उपयोग किया है जो क्षणिक है ।
यदि कोई क्षेत्र क्रमिक नहीं है, तो इसे क्षणिक चिह्नित किया जाना चाहिए। यहां हमने आइटमकॉस्टप्रिस को क्षणिक के रूप में चिह्नित किया है और यह नहीं चाहते हैं कि यह एक फ़ाइल में लिखा जाए
अब आइए नजर डालते हैं कि फाइल में किसी ऑब्जेक्ट की स्थिति कैसे लिखी जाए और फिर उसे वहां से पढ़ें।
public class SerializationExample {
public static void main(String[] args){
serialize();
deserialize();
}
public static void serialize(){
Item item = new Item(1L,"Pen", 12.55);
System.out.println("Before Serialization" + item);
FileOutputStream fileOut;
try {
fileOut = new FileOutputStream("/tmp/item.ser");
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(item);
out.close();
fileOut.close();
System.out.println("Serialized data is saved in /tmp/item.ser");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void deserialize(){
Item item;
try {
FileInputStream fileIn = new FileInputStream("/tmp/item.ser");
ObjectInputStream in = new ObjectInputStream(fileIn);
item = (Item) in.readObject();
System.out.println("Serialized data is read from /tmp/item.ser");
System.out.println("After Deserialization" + item);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
उपर्युक्त में हम किसी वस्तु के क्रमांकन और विलयन का उदाहरण देख सकते हैं।
उसके लिए हमने दो वर्गों का उपयोग किया। ऑब्जेक्ट को क्रमबद्ध करने के लिए हमने ObjectOutputStream का उपयोग किया है। हमने फाइल में ऑब्जेक्ट लिखने के लिए मेथड राइट ऑबजेक्ट का इस्तेमाल किया है।
Deserializing के लिए हमने ObjectInputStream का उपयोग किया है जो फ़ाइल से ऑब्जेक्ट से पढ़ता है। यह फ़ाइल से ऑब्जेक्ट डेटा को पढ़ने के लिए readObject का उपयोग करता है।
उपरोक्त कोड का उत्पादन निम्नानुसार होगा:
Before SerializationItem [itemId=1, itemName=Pen, itemCostPrice=12.55]
Serialized data is saved in /tmp/item.ser
After DeserializationItem [itemId=1, itemName=Pen, itemCostPrice=null]
ध्यान दें कि deserialized ऑब्जेक्ट से itemCostPrice शून्य है क्योंकि यह नहीं लिखा गया था।
Serializable को एक इंटरफ़ेस की तरह कहा जाता है, लेकिन इसकी एक ध्वज की तरह Serialization सबसिस्टम, रनटाइम पर। यह कहता है कि इस ऑब्जेक्ट को बचाया जा सकता है। सभी ऑब्जेक्ट्स अस्थिर चर को छोड़कर कोई भी अनुक्रमित ऑब्जेक्ट्स के अपवाद नहीं रखते हैं और जो अस्थिर हैं उन्हें चिह्नित किया जाएगा।
कल्पना करें कि आपका एप्लिकेशन एक विकल्प के रूप में रंग बदल सकता है, बाहरी सेटिंग के बिना आपको हर बार इसे चलाने के दौरान रंग बदलने की आवश्यकता होगी।
सीरियलाइज़ेशन एक ऐसी तकनीक है जो ऑब्जेक्ट्स और डेटा को फाइलों में स्टोर या लिखने की तकनीक है। का उपयोग करके ObjectOutputStream
और FileOutputStream
कक्षाएं। ये वर्ग वस्तुओं को बनाए रखने के लिए अपने विशिष्ट तरीके रखते हैं। पसंदwriteObject();
आंकड़ों के साथ स्पष्ट अन्वेषण के लिए। और अधिक जानकारी के लिए यहां देखें
दूसरे दृष्टिकोण से प्रस्तुत करना। सीरियलाइज़ेशन एक प्रकार का इंटरफ़ेस है जिसे 'मार्कर इंटरफ़ेस' कहा जाता है। एक मार्कर इंटरफ़ेस एक ऐसा इंटरफ़ेस है जिसमें कोई विधि घोषणाएँ नहीं होती हैं, लेकिन केवल एक क्लास होती है (या "निशान") एक वर्ग जो इंटरफ़ेस को कुछ संपत्ति के रूप में लागू करता है। यदि आप बहुरूपता को समझते हैं तो यह बहुत समझ में आएगा। Serializable मार्कर इंटरफ़ेस के मामले में, ObjectOutputStream.write (ऑब्जेक्ट) विधि विफल हो जाएगी यदि इसका तर्क इंटरफ़ेस को लागू नहीं करता है। यह जावा में एक संभावित गलती है, यह ObjectOutputStream.write (सीरियल करने योग्य) हो सकता था
अत्यधिक अनुशंसित: अधिक जानने के लिए यहोशू बलोच द्वारा प्रभावी जावा से आइटम 37 पढ़ना ।
सीरियलाइजेशन: फाइल / नेटवर्क या कहीं भी लिखने की वस्तु की स्थिति। (मतलब जावा ऑब्जेक्ट समर्थित फॉर्म फाइल सपोर्टेड फॉर्म या नेटवर्क सपोर्टेड फॉर्म के लिए)
देशीकरण: फ़ाइल / नेटवर्क या कहीं से भी वस्तु का पढ़ना। (जावा ऑब्जेक्ट सपोर्टेड फॉर्म के लिए मीन फाइल / नेटवर्क समर्थित फॉर्म)
बस अन्य उत्तरों को जोड़ने और सामान्यता के संबंध में। सीरियलाइजेशन को कभी-कभी संग्रह के रूप में जाना जाता है, उदाहरण के लिए ऑब्जेक्टिव-सी।
Serializable
:Serializability of a class is enabled by the class implementing the java.io.Serializable interface. Classes that do not implement this interface will not have any of their state serialized or deserialized. All subtypes of a serializable class are themselves serializable. The serialization interface has no methods or fields and serves only to identify the semantics of being serializable.