سؤال

عندما تنفذ الفصل Serializable في الكسوف، لدي خياران: إضافة الافتراضي serialVersionUID(1L) أو ولدت serialVersionUID(3567653491060394677L). وبعد أعتقد أن الأول هو أكثر برودة، لكن عدة مرات رأيت الأشخاص الذين يستخدمون الخيار الثاني. هل هناك أي سبب لتوليد long serialVersionUID?

هل كانت مفيدة؟

المحلول

بقدر ما أستطيع أن أقول، سيكون ذلك فقط التوافق مع الإصدارات السابقة. لن يكون هذا مفيدا إلا إذا أهملت استخدام SerialVersionUID من قبل، ثم أجريت تغييرا تعرفه متوافق ولكن الذي يسبب تسلسل لكسر.

انظر java serialization المواصفات لمزيد من التفاصيل.

نصائح أخرى

الغرض من إصدار التسلسل UID هو تتبع إصدارات مختلفة من الفصل من أجل أداء تسلسل كائنات سارية المفعول.

تتمثل الفكرة في إنشاء معرف فريد من نوعه لإصدار معين من الفئة، والذي يتم تغييره بعد ذلك عند إضافة تفاصيل جديدة إلى الفصل، مثل حقل جديد، مما يؤثر على هيكل الكائن المتسلسل.

دائما باستخدام نفس المعرف، مثل 1L يعني أنه في المستقبل، إذا تم تغيير تعريف الفصل الذي يسبب التغييرات في هيكل الكائن المتسلسل، فستكون هناك فرصة جيدة في أن تكون المشكلات عند محاولة تحيز كائن.

إذا تم حذف المعرف، فستحسب Java المعرف الخاص بك في الواقع بناء على حقول الكائن، لكنني أعتقد أنه عملية باهظة الثمن، لذلك توفير واحد يدويا سيحسن الأداء.

إليك بعض الروابط للمقالات التي تناقش التسلسل والتنسيق من الفصول الدراسية:

الأسباب الرئيسية للمرء الذي تم إنشاؤه هو جعله متوافقا مع إصدار موجود من الفصل الذي استمر بالفعل نسخا.

"طويل" الافتراضي لل serialVersionUID هي القيمة الافتراضية كما هو محدد من قبل مواصفات تسلسل جافا, ، محسوبة من سلوك التسلسل الافتراضي.

لذلك إذا قمت بإضافة رقم الإصدار الافتراضي، فستسلسل الفصول الدرجة الخاصة بك بشكل أسرع طالما لم يتغير أي شيء هيكليا، ولكن عليك أن تهتم بذلك إذا قمت بتغيير الفئة (إضافة / إزالة الحقول)، فأنت تقوم أيضا بتحديث رقم سري.

إذا لم يكن لديك متوافق مع تدفقات بت الموجودة، فيمكنك فقط وضعها 1L هناك وزيادة الإصدار حسب الحاجة عند تغيير شيء ما. وهذا هو، عند إصدار التسلسل الافتراضي من الفئة المتغيرة يختلف عن الإصدار الافتراضي للفئة القديمة.

أنت بالتأكيد يجب أن تخلق SerialVersionUID في كل مرة تحدد فيها فئة تنفذ java.io.Serializable. وبعد إذا لم تكن كذلك، فسيتم إنشاء واحد لك تلقائيا، لكن هذا سيء. يعتمد SerialVerVerVerNuid المولود التلقائي على توقيعات طريقة الفصل الخاص بك، لذلك إذا قمت بتغيير فصلك في المستقبل لإضافة طريقة (على سبيل المثال)، فسوف تفشل في إصدارات "القديمة" من الفصل. إليك ما يمكن أن يحدث:

  1. قم بإنشاء الإصدار الأول من فصلك، دون تحديد SerialVersionUID.
  2. تسلسل مثيل فصلك إلى متجر مستمر؛ يتم إنشاء SerialVersionUID تلقائيا لك.
  3. تعديل الفصل الخاص بك لإضافة طريقة جديدة، وإعادة نشر التطبيق الخاص بك.
  4. محاولة لتحمل المثيل الذي تم تسلسله في الخطوة 2، ولكن الآن فشل (عندما يجب أن ينجح)، لأنه يحتوي على SerialVersionUID المولدة تلقائيا.

إذا لم تحدد SerialVersionUID، فإن جافا يجعل واحدة على الطاير. serialversionuid المولدة هو هذا الرقم. إذا قمت بتغيير شيء ما في فصلك، فلا يجري فصلك الفائض من فصولك المسلقة السابقة ولكنك يغير التجزئة، فأنت بحاجة إلى استخدام SerialVersionUID الكبير للغاية (أو الرقم "المتوقع" من رسالة الخطأ) وبعد خلاف ذلك، إذا كنت تتبع كل شيء بنفسك، 0، 1، 2 ... هو أفضل.

عند استخدام SerialVersionUID (1L) بدلا من إنشاء SerialVersionUID (3567653491060394677L) أنت تقول شيئا.

أنت تقول أنك ثقة بنسبة 100٪ أنه لا يوجد نظام سيسطر بهذه الفئة التي تحتوي على نسخة متسلسلة غير متوافقة من هذه الفئة مع إصدار إصدار من 1.

إذا كنت تستطيع التفكير في أي عذر لسجل الإصدار المسلسل غير معروف، فقد يكون من الصعب القول بالثقة. في حياته، سيتم الحفاظ على فئة ناجحة من قبل العديد من الأشخاص، ويعيشون في العديد من المشاريع، ويقيمون في العديد من النظم.

يمكنك الاطلاع على ذلك. أو يمكنك أن تلعب اليانصيب على أمل أن تخسر. إذا قمت بإنشاء الإصدار الذي لديك فرصة صغيرة للأشياء التي تسير. إذا افترضت "مهلا أراهن أن أحد يستخدم 1 بعد" احتمالاتك أكبر من صغيرة. إنه على وجه التحديد لأننا جميعا نفكر 0 و 1 بارد أن لديك احتمالات أعلى من ضربها.

-

عند إنشاء SerialVersionUID (3567653491060394677L) بدلا من استخدام SerialVersionUID (1L) أنت تقول شيئا.

أنت تقول أن الناس قد يكون إما أنشئوا يدويا أو أنشأوا أرقام إصدار أخرى عبر محفوظات هذه الفئة ولا تهتم لأن وقت طويل ينقط أرقاما كبيرة.

في كلتا الحالتين إلا إذا كنت تعرف تماما تاريخ أرقام الإصدارات المستخدمة عند تسلسل الفئة في الكون بأكمله حيث يحتوي عليه أو سيكون موجودا من أي وقت مضى، فأنت تتخذ فرصة. إذا كان لديك الوقت لجعل 100٪ متأكدا 1 هو AOK، فانتقل إليه. إذا كان ذلك الكثير من العمل، فافعل إلى الأمام وتولد الأعماق. من المرجح أن تفوز في اليانصيب من أن يكون هذا خطأ. إذا فعل ذلك، اسمحوا لي أن أعرف وسأشتري لك بيرة.

مع كل هذا الحديث عن لعب اليانصيب قد أعطيتك الانطباع بأن SerialVersionUID يتم إنشاؤه بشكل عشوائي. في الواقع طالما أن مجموعة الأرقام توزع بالتساوي على كل قيمة ممكنة لفترة طويلة سيكون على ما يرام. ومع ذلك، فقد فعل ذلك بهذه الطريقة:

http://docs.oracle.com/javase/6/docs/platform/serialization/spec/class.html#4100.

الفرق الوحيد الذي تحصل عليه مع ذلك هو أنك لا تحتاج إلى مصدر عشوائي. أنت تستخدم التغييرات في الفصل نفسه لتغيير النتيجة. ولكن وفقا لمبدأ Pigeonhole، لا تزال هناك فرصة يمكن أن تخطئها ولديها تصادم. انها غير مرجح للغاية بشكل لا يصدق. حظا سعيدا في الحصول على بيرة مني.

ومع ذلك، حتى لو كان الفصل سيعيش إلا في نظام واحد وقاعدة شفرة واحدة، والتفكير بأن زيادة الرقم باليد يمنحك فرصة الصفر للاصطدام فقط يعني أنك لا تفهم البشر. :)

حسنا، SerialVersionuid استثناء للحكم الذي "الحقول الثابتة لا تحصل على تسلسل". يكتب ObjectOutPuttream في كل مرة قيمة serialversionuid إلى دفق الإخراج. يقوم ObjectInPutstream بقراءة ذلك وإذا كانت القيمة تقرأ من الدفق لا توافق على قيمة SerialVersionUID في الإصدار الحالي من الفئة، فهذا يطرح InvalidClasSexception. علاوة على ذلك، إذا لم يكن هناك serialversionuid المعلن رسميا في الفصل لتسليط التسلسل، يضيف مترجم تلقائيا إلى قيمة تم إنشاؤها بناء على الحقول المعلنة في الفصل.

لأنه في العديد من الحالات المعرف الافتراضي ليس فريدا. لذلك نخلق معرف لصنع مفهوم فريد.

لإضافة إلى David SCHMITTS الإجابة، كقاعدة عامة، سأستفيد دائما 1L خارج الاتفاقية. لقد اضطررت فقط إلى العودة وتغيير بعضها عدة مرات، لكنني عرفت أنه عندما قمت بالتغيير وتحديث الرقم الافتراضي من قبل واحد في كل مرة.

في شركتي الحالية، يحتاجون إلى الرقم الذي تم إنشاؤه تلقائيا، لذلك يمكنني استخدام ذلك بالنسبة للاتفاقية، لكنني أفضل الافتراضي. متناولي هو، إذا لم تكن اتفاقية تعمل فيها، فاستخدم الافتراضي، إلا إذا كنت تعتقد أنك ستغير باستمرار هيكل الفصول المسلقة لسبب ما.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top