في الآونة الأخيرة ، قمت بتجميع المعرفة الأساسية لـ Java ، وقد تم حل المعلومات المتعلقة بتسلسل Java وفرسها بالتفصيل. سوف أتناول ملاحظة هنا ، على أمل أن تساعد أيضًا الأصدقاء الذين قرأوا هذا المقال.
1. مفهوم التسلسل والخروج
تسمى عملية تحويل كائن إلى تسلسل بايت التسلسل لكائن ما.
تسمى عملية استعادة تسلسل البايت إلى كائن ما تخلص من كائن.
هناك استخدامان رئيسيان للتسلسل للكائنات:
1) احفظ تسلسل البايت للكائنات بشكل دائم على القرص الثابت ، عادة في ملف ؛
2) نقل تسلسل البايت للكائنات على الشبكة.
في العديد من التطبيقات ، يجب أن يتم تسلسل بعض الكائنات ، بحيث تترك مساحة الذاكرة والانتقال إلى القرص الصلب المادي للتخزين على المدى الطويل. على سبيل المثال ، الأكثر شيوعًا هو كائن الجلسة في خادم الويب. عندما يصل 100000 مستخدم بشكل متزامن ، قد يظهر 100000 كائن جلسة ، وقد لا تكون الذاكرة قادرة على تحملها. لذلك ، ستقوم حاوية الويب بتسلسل بعض الرؤية إلى القرص الثابت أولاً ، وانتظر حتى يتم استخدامها ، ثم استعادة الكائنات المحفوظة في القرص الثابت إلى الذاكرة.
عندما تتواصل عمليتان عن بُعد ، يمكنهم إرسال أنواع مختلفة من البيانات إلى بعضها البعض. بغض النظر عن نوع البيانات ، سيتم نقله على الشبكة في شكل تسلسل ثنائي. يحتاج المرسل إلى تحويل كائن Java إلى سلسلة من البايتات من أجل نقله على الشبكة ؛ يحتاج المتلقي إلى استعادة البايتات إلى كائن Java.
2. API التسلسلي في مكتبة فئة JDK
يمثل java.io.objectoutoutputstream دفق إخراج الكائن. يمكن أن تقوم طريقة WriteObject (Object OBJ) بتسلسل كائن OBJ المحدد بواسطة المعلمة وكتابة تسلسل البايت الذي تم الحصول عليه إلى دفق الإخراج الهدف.
يمثل java.io.objectInputStream دفق إدخال الكائن. تقرأ طريقة ReadObject () تسلسل البايت من دفق إدخال المصدر ، ويغضبها في كائن ما ، ويعيدها.
يمكن تسلسل الكائنات فقط من الفئات التي تنفذ واجهات قابلة للتسلسل وقابلة للخارجية. الواجهة الخارجية ترث من الواجهة التسلسلية. تتحكم الفئات التي تنفذ الواجهة الخارجية تمامًا في سلوك التسلسل ، في حين أن الفئات التي تنفذ فقط الواجهة القابلة للتسلسل يمكن أن تعتمد طريقة التسلسل الافتراضية.
يتضمن التسلسل الكائن الخطوات التالية:
1) إنشاء دفق إخراج الكائن ، والذي يمكنه لف نوع آخر من دفق الإخراج الهدف ، مثل دفق إخراج الملف ؛
2) اكتب الكائن من خلال طريقة TrintObject () لدفق إخراج الكائن.
خطوات إلغاء التخلص من الكائن هي كما يلي:
1) إنشاء دفق إدخال كائن يمكنه لف نوع مختلف من دفق إدخال المصدر ، مثل دفق إدخال الملف ؛
2) اقرأ الكائن من خلال طريقة ReadObject () لدفق إدخال الكائن.
أمثلة التسلسلية والكائنات:
تحديد فئة الشخص لتنفيذ الواجهة التسلسلية
1 استيراد java.io.serializable ؛ 2 3 /** 4 * <p> classname: person <p> 5 * <p> الوصف: اختبار كائن التسلسل و deserialization <p> 6 * author xudp 7 * version 1.0 v 8 * createTime 2014-6-9 02:33:25 pm 9 * /10 public personments {11 12 /** -5809782578272943999L ؛ 16 العمر الخاص بعمر int ؛ 17 اسم سلسلة خاصة ؛ 18 سلسلة جنسية خاصة ؛ 19 20 عامًا عامة int getage () {21 return Age ؛ 22} 23 24 String Public String getName () {25 return Name ؛ } 35 36 public void setName (اسم السلسلة) {37 this.name = name ؛ 38} 39 40 public void setsex (سلسلة الجنس) {41 this.sex = sex ؛ 42} 43}تسلسل وتهرب من كائنات فئة الشخص
استيراد java.io.file ؛ استيراد java.io.fileInputStream ؛ استيراد java.io.filenotfoundException ؛ استيراد java.io.fileOutputStream ؛ استيراد java.io.ioException ؛ import java.io.objectinputstream TestObjSerializeAndSerialize <p> * <p> الوصف: تسلسل وتجاهل كائنات الاختبار <p> * Auuthor Xudp * version 1.0 V * CreateTime 2014-6-9 03:17:25 PM */public class testobjserializeanddedserialize {public static void main serializeperson () ؛ // serialize profer person p = deserializeperson () ؛ // deserial perons object system.out.println (messageformat.format ("name = {0} ، age = {1} ، sex = {2}" ، p.getName () ، p.getage () ، p.getsex ()) ؛ } / ** * methodname: serializeperson * الوصف: كائن الشخص المسلسل * Author xudp * throws fileNotFoundException * throws ioException * / private static void serializeperson () reming filenotfoundException ، ioException {person = new person = جديد () ؛ person.setName ("gacl") ؛ person.setage (25) ؛ person.setSex ("ذكر") ؛ // ObjectOutputStream Optuting Dream ، قم بتخزين كائن الشخص في ملف PRISON.TXT على القرص E ، وأكمل عملية التسلسل لكائن الشخص. ObjectOutputStream oo = new ObjectOutputStream (FileOutputStream جديد (ملف جديد ("E: /Person.txt"))) ؛ oo.writeObject (شخص) ؛ system.out.println ("تم تسلسل الشخصيات الشخصي بنجاح!") ؛ oo.close () ؛ }/** * methodname: deserializeperson * الوصف: كائن deserializeperson * author xudp * return * athrows استثناء * throws ioException */private static person deserializeperson () استثناء (e: " شخص شخص = (شخص) ois.ReadObject () ؛ System.out.println ("الشخص الذي يفرزه كائن النجاح!") ؛ عودة الشخص }}نتائج تشغيل الكود كما يلي:
بعد تسلسل الشخص بنجاح ، تم إنشاء ملف profire.txt على القرص E ، بينما يتم استخدام الشخص الذي يفرغ من الشخص لقراءة person.txt of e disk.
3. دور التسلسل
Seri al versi ui d: يعني حرفيًا رقم الإصدار المسلسل. جميع الفئات التي تنفذ الواجهة التسلسلية لها متغير ثابت يمثل معرف الإصدار المسلسل.
خاص ثابت نهائي طويل المسبانيويد
إذا لم تتم إضافة SerialVersionuid إلى الفصل ، فسيظهر التحذير التالي.
سيؤدي النقر مع الماوس إلى طرح مربع حوار يولد SerialVersionuid ، كما هو موضح في الشكل أدناه:
هناك طريقتان لتوليد SerialVersionuid:
SerialVersionuid المتولد بهذه الطريقة هو 1L ، على سبيل المثال:
خاص ثابت نهائي طويل المسبانيويد = 1L ؛
يتم إنشاء SerialVersionuid المتولد بهذه الطريقة بناءً على اسم الفصل واسم الواجهة والطريقة والسمة ، وما إلى ذلك ، على سبيل المثال:
استاتيكي خاص نهائي الطويل المسلسل = 4603642343377807741L ؛
بعد الإضافة ، لن يظهر التحذير ، كما هو موضح أدناه:
بعد الحديث عنها ، ما هو استخدام SerialVersionuid (رقم الإصدار المسلسل)؟ دعونا نستخدم المثال التالي لتوضيح دور SerialVersionuid ، ومعرفة الكود التالي:
1 استيراد java.io.file ؛ 2 استيراد java.io.fileInputStream ؛ 3 استيراد java.io.filenotfoundException ؛ 4 استيراد java.io.fileOutputStream ؛ 5 استيراد java.io.ioException ؛ 6 استيراد java.io.objectinputStream ؛ 7 استيراد java.io.objectOutputStream ؛ 8 استيراد java.io.serializable ؛ 9 10 اختبار الفئة العامة testSerialVersionuid {11 12 Public Static Void Main (String [] args) يرمي الاستثناء {13 SerializeCustomer () ؛ // serialize consure courte 14 customer customer = deserializeCustomer () Author xudp22 * throws fileNotFoundException23 * throws ioException24 */25 خاصًا باطلبًا ثابتًا serializeCustomer () يلقي FileNotFoundException ، 26 iOexception {27 customer = new customer ("gacl" ، 25) ملف جديد ("e: /customer.txt"))) ؛ 31 oo.writeObject (العميل) ؛ 32 System.out.println ("تسلسل كائن العميل بنجاح!") ؛ 33 oo.close () ؛ 34} 35 36 /** @return41 * throws استثناء 42 * throws ioException43 */44 خاصًا بسكان عميل ثابت خاص deseriizeCustomer () يلقي الاستثناء ، IOException {45 ObjectInputStream ois = new ObjectInputStream (fileInputStream جديد (46 ملفًا جديدًا ("e: /customer.txt System.out.println ("كان ناجح كائن العميل ناجحًا! ") ؛ 49 إرجاع العميل ؛ 50} 51} 52 53 /** 54 * <p> اسم classname: العميل <p> 55 * <p> الوصف: يقوم العميل بتنفيذ الواجهة القابلة للتسلسل ويمكن أن يتم تسلسله <p> 56 * @Author Xudp57 * @Version 1.0 v58 * @createTime 2014-6-9 04: 20: 1759 {61 // no SerialVersionUid62 اسم السلسلة الخاصة ؛ 63 عمري private ؛ 64 65 العميل العام (اسم السلسلة ، int) {66 this.name = name ؛ 67 this.age = age ؛ 68} 69 70 / * 71 * methodname string75 * see java.lang.object#toString () 76 */77 @override78 السلسلة العامة toString () {79 return "name =" + name + "، Age =" + Age ؛ 80} 81}نتائج التشغيل:
كل من التسلسل وفرس الناجحة كانت ناجحة.
دعنا نعدل فئة العميل وإضافة سمة جنسية إضافية ، على النحو التالي:
1 فئة العميل ينفذ قابلة للتسلسل {2 // لا يتم تعريف SerialVersionuid في اسم السلسلة الخاصة من فئة العميل 3 ؛ 4 عصر int الخاص ؛ 5 6 // سمة الجنس الجديدة 7 سلسلة جنسية خاصة ؛ 8 9 9 العميل العام (اسم السلسلة ، int age) {10 this.name = name ؛ 11 this.age = age ؛ 12} 13 14 العميل العام (اسم السلسلة ، int age ، string sex) {15 this.name = name ؛ xudp24 * regurn string25 * see java.lang.object#toString () 26 */27 @verride28 public string toString () {29 return "name =" + name + "، age =" + age ؛ 30} 31}ثم قم بتنفيذ عملية desequence ، وسيتم طرح معلومات الاستثناء التالية:
1 استثناء في الموضوع "الرئيسي" java.io.invalidclassexception: العميل ؛ 2 فئة محلية غير متوافقة: 3 دفق classdesc serialversionuid = -88175599799432325 ، 4 فئة محلية SerialVersionuid = -5182532647273106745
هذا يعني أن الفصل في دفق الملفات والفئة في classpath ، أي الفئة المعدلة ، غير متوافقة. هم تحت اعتبارات آلية الأمن. البرنامج يرمي خطأ ويرفض تحميل. فماذا لو كانت لدينا بالفعل حاجة لإضافة حقل أو طريقة بعد التسلسل؟ ماذا علي أن أفعل؟ وهذا هو تحديد SerialVersionuid بنفسك. في مثال TestSerialVersionuid ، إذا لم يتم تحديد المسلسل المسلسل لفئة العميل ، فإن برنامج التحويل البرمجي Java سيؤدي تلقائيًا خوارزمية موجزة لهذه الفئة ، على غرار خوارزمية البصمات. طالما أن الملف يحتوي على مساحة واحدة أخرى ، فإن UID الناتج سيكون مختلفًا تمامًا ، والذي يمكن ضمان أن يكون هذا الرقم فريدًا بين العديد من الفئات. لذلك ، بعد إضافة حقل ، نظرًا لعدم تحديد SerialVersionuid ، يقوم المترجم بإنشاء UID بالنسبة لنا ، وهو بالطبع ليس هو نفسه الذي تم حفظه في الملف من قبل ، لذلك هناك خطأان مع أرقام إصدار تسلسل غير متناسقة. لذلك ، طالما نحدد SerialVersionuid أنفسنا ، يمكننا إضافة حقل أو طريقة بعد التسلسل دون التأثير على الاستعادة اللاحقة. لا يزال من الممكن استخدام الكائن المستعاد ، وهناك أيضًا المزيد من الطرق أو السمات المراد استخدامها.
بعد ذلك ، استمر في تعديل فئة العملاء وتحديد SerialVersionuid للعميل. الرمز المعدل كما يلي:
يقوم عميل الفئة بتنفيذ Serializable { / ** * SerialVersionuid (رقم الإصدار المسلسل) المحدد في فئة العميل * / private Static Final Long SerialVersionuid = -5182532647273106745L ؛ اسم السلسلة الخاصة ؛ عصر INT الخاص ؛ // سمة الجنس الجديدة // سلسلة جنسية خاصة ؛ العميل العام (اسم السلسلة ، int age) {this.name = name ؛ this.age = العمر ؛ } /*العميل العام (اسم السلسلة ، int ، string sex) {this.name = name ؛ this.age = العمر ؛ this.Sex = الجنس ؛ } *// * * @methodname toString * description أعد كتابة toString () طريقة فئة الكائن * Author xudp * @regire * see java.lang.object#tostring () */ @أوفر ريد السلسلة toString () }}إعادة تنفيذ عملية التسلسل ، قم بتسلسل كائن العميل إلى تخزين ملف customer.txt على القرص الثابت المحلي ، ثم قم بتعديل فئة العميل وإضافة سمة الجنس. رمز فئة العميل المعدل كما يلي:
يقوم عميل الفئة بتنفيذ Serializable { / ** * SerialVersionuid (رقم الإصدار المسلسل) المحدد في فئة العميل * / private Static Final Long SerialVersionuid = -5182532647273106745L ؛ اسم السلسلة الخاصة ؛ عصر INT الخاص ؛ // جنس جديد سمة سلسلة جنسية خاصة ؛ العميل العام (اسم السلسلة ، int age) {this.name = name ؛ this.age = العمر ؛ } العميل العام (اسم السلسلة ، int ، string sex) {this.name = name ؛ this.age = العمر ؛ this.Sex = الجنس ؛ } / * * methodname toString * description أعد كتابة طريقة toString () لفئة الكائن * Author xudp * @sturn * @see java.lang.object#toString () * / Override public toString () }}قم بإجراء عملية desequence ، وسوف يكون Desequence ناجحًا هذه المرة ، كما هو موضح أدناه:
4. قيمة SerialVersionuid
يتم إنشاء قيمة SerialVersionuid تلقائيًا بواسطة بيئة وقت تشغيل Java استنادًا إلى التفاصيل الداخلية للفئة. إذا تم تعديل رمز المصدر للفئة وإعادة تنسيقه ، فقد تتغير قيمة التسلسل المسلسل لملف الفئة الذي تم إنشاؤه حديثًا.
تعتمد القيمة الافتراضية لـ SerialVersionuid للفئة بالكامل على تنفيذ مترجم Java. لنفس الفئة ، قد يؤدي التجميع مع مجمعات Java المختلفة إلى إبرام تسلسل مختلف ، وقد يكون أيضًا هو نفسه. لتحسين استقلال وتأكد من SerialVersionuid ، يوصى بشدة بتحديد SerialVersionuid المعروض في فئة قابلة للتسلسل ، وتعيينها قيمة واضحة.
هناك غرضان لتحديد SerialVersionuid بشكل صريح:
1. في بعض الحالات ، من المتوقع أن تكون الإصدارات المختلفة من الفصل متوافقة مع التسلسل ، لذلك من الضروري التأكد من أن إصدارات مختلفة من الفصل لها نفس التسلسل.
2. في بعض الحالات ، من غير المتوقع أن تكون الإصدارات المختلفة من الفصل متوافقة مع التسلسل ، لذلك من الضروري التأكد من أن إصدارات مختلفة من الفصل لها مختلف التسلسل.
شكرا لك على القراءة ، آمل أن تساعدك. شكرا لك على دعمك لهذا الموقع!