تصف هذه المقالة تسلسل الكائنات والخروج في Java. شاركه للجميع للرجوع إليه. التفاصيل كما يلي:
1. مقدمة
يشير تسلسل الكائن إلى عملية تحويل كائن إلى سلسلة من البايتات ، في حين أن التخلص من التخلص هو عملية استعادة كائن بناءً على تسلسل بايت.
يستخدم التسلسل بشكل عام في السيناريوهات التالية:
1. احفظ الكائن بشكل دائم وحفظ تسلسل البايت للكائن إلى الملف المحلي ؛
2. تمرير الكائنات في الشبكة عن طريق تسلسلها ؛
3. تمرير الكائنات بين العمليات من خلال التسلسل.
يجب أن ينفذ الفئة التي ينتمي إليها الكائن الواجهة التسلسلية أو القابلة للخارجية. بالنسبة إلى الفئات التي تنفذ الواجهة التسلسلية ، تتبنى التسلسل وتجاهل طريقة التسلسل الافتراضي.
تمثل java.io.objectoutOutputStream دفق إخراج الكائن ، ويمكن للطريقة التي يمكن أن تدركها (Object OBJ) التسلسل للكائن وكتابة تسلسل البايت الذي تم الحصول عليه إلى دفق الإخراج الهدف.
تمثل java.io.objectInputStream دفق إدخال الكائن ، ويمكن أن تقرأ طريقة ReadObject () سلسلة من البايتات من دفق الإدخال المصدر ، وتجاهله في كائن ، وإعادته.
2. عدة طرق للتسلسل
لنفترض أنه يتم تعريف فئة العميل ، اعتمادًا على طريقة التسلسل الخاصة بالعميل ، قد تكون هناك طرق التسلسل التالية:
1. تنفيذ أساليب READOBJECTIBLE القابلة للتسلسل وغير المحددة
يستخدم ObjectOutputStream JDK لتسلسل متغيرات مثيل غير رابطة لكائن العميل بشكل افتراضي ؛
ObjectInputStream تخلص من متغيرات المثيل غير المترجم لكائن العميل باستخدام طريقة JDK الافتراضية.
2. تنفيذ أساليب التسلسل وتحديد أساليب ReadObject و WriteObject
يستدعي ObjectOutputStream طريقة TrintObject (ObjectOutputStream) لفئة العميل لتسلسل متغيرات المثيل غير المترابط لكائن العميل ؛
يستدعي ObjectInputStream طريقة ReadObject (ObjectInputStream) لفئة العميل لإلغاء التخلص من متغيرات المثيل غير المقلدة لكائن العميل.
3. تنفيذ طرق خارجية وتحديد طرق القراءة والكتابة
يستدعي ObjectOutputStream طريقة الكتابة على فئة العميل لتسلسل متغيرات المثيل غير المقيد لكائن العميل ؛
يقوم ObjectInputStream أولاً بتثبيت كائن من خلال مُنشئ بدون معلمة لفئة العميل ، ثم يستعطِّل متغير المثيل غير المترابط لكائن العميل باستخدام طريقة القراءة.
3. واجهة قابلة للتسلسل
يتيح الفصل وظائف التسلسل الخاصة به من خلال تنفيذ واجهة java.io.serializable. لن تكون الفصول التي لا تنفذ هذه الواجهة قادرة على إجراء تسلسل أو تخلص من أي من ولاياتها. جميع الأنواع الفرعية للطبقة المتسلسلة هي نفسها قابلة للتسلسل. لا تحتوي واجهة التسلسل على طرق أو حقول ولا تستخدم إلا لتحديد الدلالات القابلة للتسلسل.
أثناء عملية التخلص من التهوية ، سيتم تهيئة حقول الفئة غير المخصصة باستخدام مُنشئ المعلمة الشائع أو المحمي للفئة. يجب أن تكون الفئة الفرعية القابلة للتسلسل قادرة على الوصول إلى مُنشئ المعلمة. سيتم استعادة الحقول التي يمكن أن تكون فئات فرعية قابلة للتسلسل من التيار.
عند اجتياز عرض الفصل ، قد تواجه كائنات لا تدعم الواجهة القابلة للتسلسل. في هذه الحالة ، يتم إلقاء NotserializableException ويتم تحديد الفصل غير القابل للتسلسل.
1. توقيع دقيق
يجب أن تنفذ الفئات التي تتطلب معالجة خاصة أثناء التسلسل والتسلسل طرقًا خاصة باستخدام التواقيع الدقيقة التالية:
private void writeObject (java.io.objectoutOutputStream) يلقي ioException
private void readObject (java.io.objectinputStream in) يلقي iOexception ، classnotfoundException ؛
private void readobjectnodata () يلقي ObjectStreamException ؛
طريقة الكتابة المسؤولة عن كتابة حالة كائن من فئة معينة بحيث يمكن لطريقة ReadObject المقابلة استعادتها. يمكن استدعاء الآلية الافتراضية لإنقاذ حقول الكائن عن طريق استدعاء out.defaultWriteObject. لا تحتاج الطريقة بحد ذاتها إلى إشراك دول تنتمي إلى فئة الفئة الفائقة أو الفئة الفرعية. يمكن حفظ الحالة عن طريق كتابة الحقول الفردية إلى ObjectOutputStream باستخدام طريقة WriteObject أو استخدام الطريقة التي تدعمها DataOutput لأنواع البيانات الأساسية.
طريقة ReadObject مسؤولة عن قراءة واستعادة حقول الفصل من الدفق. يمكنه الاتصال بـ. defaultReadObject لاستدعاء الآلية الافتراضية لاستعادة الحقول غير المستقلة وغير المنقولة للكائن. تستخدم طريقة defaultReadObject المعلومات في الدفق لتخصيص حقول الكائنات في الدفق الذي يتم حفظه من خلال الحقول المحددة المقابلة في الكائن الحالي. يستخدم هذا للتعامل مع المواقف التي يجب إضافتها حقول جديدة بعد تطور الفصل. لا تحتاج الطريقة بحد ذاتها إلى إشراك دول تنتمي إلى فئة الفئة الفائقة أو الفئة الفرعية. يمكن حفظ الحالة عن طريق كتابة الحقول الفردية إلى ObjectOutputStream باستخدام طريقة WriteObject أو استخدام الطريقة التي تدعمها DataOutput لأنواع البيانات الأساسية.
في الحالة التي لا يسرد فيها دفق التسلسل الفئة المعطاة على أنها الفئة الفائقة المراد إلحاقها ، تكون طريقة ReadObjectNodata مسؤولة عن تهيئة حالة الكائن لفئة معينة. يحدث هذا عندما تختلف فئة مثيل Deserialized المستخدم من قبل المتلقي عن المرسل والفئة الممتدة بواسطة إصدار المتلقي ليست فئة ممتدة بواسطة إصدار المرسل. يحدث أيضًا عندما يتم العبث بتيار التسلسل ؛
عند كتابة كائنات إلى دفق ، تحتاج إلى تحديد الفئة القابلة للتسلسل للكائن البديل لاستخدامها ، ويجب عليك تنفيذ هذه الطريقة الخاصة بتوقيع دقيق:
any-Access-Modifier Object Writereplace () يلقي ObjectStreamException ؛
سيتم استدعاء طريقة الكتابة هذه عن طريق التسلسل ، شريطة أن تكون هذه الطريقة موجودة ، ويمكن الوصول إليها بواسطة طريقة محددة في فئة الكائن المسلسل. لذلك ، يمكن أن يكون لهذه الطريقة وصول خاص ومحمي وذات حزمة خاصة. يتبع وصول الفئة الفرعية إلى هذه الطريقة قواعد الوصول إلى Java.
عند قراءة مثيل فئة من دفق ، تحتاج إلى تحديد التوقيع الدقيق الذي يجب أن تستخدمه الفئة البديلة لتنفيذ هذه الطريقة الخاصة.
أي كائن aded-modifier readResolve () يلقي ObjectStreamException ؛
تتبع طريقة ReadResolve هذه قواعد الاتصال نفسها وقواعد الوصول مثل WriterePlace.
إذا حددت الفئة طريقة ReadResolve ، فسيتم استدعاء طريقة ReadResolve في نهاية التخلص من التسلسل ، والكائن الذي تم إرجاعه بواسطة الطريقة هو النتيجة النهائية لسلطة التخلص.
2.serialversionuid
يستخدم وقت التشغيل التسلسلي رقم إصدار يسمى SerialVersionuid للربط مع كل فئة قابلة للتسلسل ، والذي يتم استخدامه أثناء التخلص من التحقق من أن المرسل ومستقبل الكائن المسلسل الذي تم تحميله للكائن. إذا قام المتلقي بتحميل SerialVersionuid لفئة الكائن مختلفة عن رقم إصدار المرسل المقابل ، فإن إزالة الإرهاق سيؤدي إلى وجود غير صالح. يمكن للطبقة القابلة للتسلسل أن تعلن صراحة تصنيفها الخاص بإعلان حقل يسمى "SerialVersionuid" (يجب أن يكون هذا المجال حقلًا طويلًا ثابتًا ونهائيًا):
أي ancess-modifier static static fong serialversionuid = 42l ؛
إذا لم تعلن الفئة المتسلسلة بشكل صريح ، فإن وقت تشغيل التسلسل يحسب القيمة التسلسلية التسلسلية للصف الفئة القائمة على جوانب مختلفة من الفئة ، كما هو موضح في "مواصفات كائن Java (TM)". ومع ذلك ، يوصى بشدة أن تعلن جميع الفئات القابلة للتسلسل بشكل صريح القيم التسلسلية ، لأن حساب التسلسل التسلسلي الافتراضي حساس للغاية لتفاصيل الفصل ، وقد تختلف اختلافًا كبيرًا تبعًا لتنفيذ المترجم ، لذلك في عملية الاستهلاك غير المتوقعة المعتدل. قد ينتج. لذلك ، لضمان الاتساق بين القيم التسلسلية عبر مجمعات Java المختلفة ، يجب أن تعلن الفئة المسلسل عن قيمة التسلسل الصريح. يوصى بشدة أيضًا باستخدام المعدل الخاص لعرض التصريح التسلسلي إذا كان ذلك ممكنًا لأن هذه التصريحات تستخدم فقط لإعلان الفئة مباشرة - الحقل التسلسلي كعضو موروث لا فائدة منه. لا يمكن أن تعلن فئات الصفيف عن التسلسل الصريح ، لذلك يكون لها دائمًا القيمة المحسوبة الافتراضية ، لكن فئات الصفيف لا تتطابق مع متطلبات القيمة التسلسلية.
3. واجهة externalizable
القابلة للاتصالات هو امتداد للسرد.
استدعاء طريقة الفئة الكتابة على الأقدام أثناء التسلسل ، وتهرب من طريقة القراءة المحلية ؛
عند إجراء التهوية ، يسمى مُنشئ المعلمة بالفئة أولاً ، وهو ما يختلف عن التسلسل الافتراضي.
رابع ، ملخص
إذا تم اعتماد طريقة التسلسل الافتراضي ، طالما أن الفصل ينفذ الواجهة القابلة للتسلسل ، يمكن تسلسل مثيله. بشكل عام ، يجب أن تحاول الفئات المصممة خصيصًا للميراث عدم تنفيذ الواجهة القابلة للتسلسل ، لأنه بمجرد أن تنفذ الفئة الأم للواجهة التسلسلية ، تكون جميع فئاتها قابلة للتسلسل.
أوجه القصور في طريقة التسلسل الافتراضي:
1. ليس من الآمن إجراء تسلسل بيانات حساسة مباشرة غير مناسبة للكشف عن الكائن ؛
2. لن يتحقق مما إذا كانت متغيرات الأعضاء للكائن تفي بالقيود الصحيحة ، وقد يتم العبث بالبيانات وتتسبب في تشغيل غير طبيعي ؛
3. مطلوب اجتياز الرسم البياني الكائن.
4. اجعل واجهة الفئة مقيدة بالتنفيذ الداخلي للفئة ، مما يقيد ترقية الفئة وصيانتها.
من خلال تنفيذ النوع الخاص tructoBject () و readObject () للواجهة القابلة للتسلسل ، أو تنفيذ الواجهة الخارجية القابلة للتطبيق ، وتنفيذ أساليب الكتابة () و readexternal () ، وتوفير مُنشئ من النوع العام بدون طريقين للسيطرة على عملية التسلسل. يمكن أن تتجنب بشكل فعال أوجه القصور في طريقة التسلسل الافتراضي.
من المأمول أن يكون هذا المقال مفيدًا لتصميم برنامج Java للجميع.