ما هي السلوكيات الشائعة غير المحددة التي يجب أن يعرفها مبرمجو Java

StackOverflow https://stackoverflow.com/questions/376338

  •  22-08-2019
  •  | 
  •  

سؤال

كمثل هذا سؤال ولكن لجافا

تحديثبناءً على تعليقات وردود بعض الأشخاص، من الواضح أن Java لديها القليل جدًا من السلوك غير المحدد.

لذلك أود أن أسأل أيضًا ما هو السلوك الذي لا يعتبر كذلك بديهي. الرجاء عند الرد التمييز بين الاثنين :)

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

المحلول

أي شيء يتعلق بالخيوط..:)

أيضًا:

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

نصائح أخرى

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

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

المنطقة الرئيسية التي يحدث فيها سلوك غير محدد هي التوقيت الدقيق والجدول الزمني لسلاسل رسائل متعددة (كما ذكر توم هاوتن بالفعل)..

هناك العديد من الأماكن التي لا يكون فيها السلوك واضحًا، لذلك قد يبدو غير محدد، لكنه ليس كذلك (أمثلة مقارنة السلسلة التي قدمها أوسكار رييس هي مثال رائع).

وعدد قليل من الأماكن التي يتم فيها تعريف السلوك على أنه غير محدد (على سبيل المثال، يتم تعريف ترتيب العناصر في HashMap على أنه يعتمد على التنفيذ ولا يلزم أن يكون ثابتًا).

اعتقد انه ألغاز Java(TM):الفخاخ والمزالق وحالات الزاوية سيكون الكتاب مفيدًا جدًا، فهو يشرح العديد من النقاط المخفية والسلوكيات غير المحددة لجافا.

التسلسل.إنها ليست غير محددة في حد ذاتها (هناك خوارزمية حتمية).ومع ذلك، ليس من الواضح على الإطلاق للمراقب العادي ما الذي سيؤدي أو لا يسبب تغييرًا في serialVersionUID، وبالتالي إحباط جميع محاولاتك للاستفادة من RMI وJMS ومجموعة متنوعة من الاختصارات الأخرى.

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

private static final long serialVersionUID = 1L;

قم فقط بتغيير قيمة هذا الحقل عندما تقوم أنت، المطور يعرف أنه كان هناك تغيير يقتل التوافق في التعليمات البرمجية الخاصة بك.لا تدع JDK يتخذ هذا القرار نيابةً عنك....

لست متأكدًا تمامًا مما تقصده بـ "السلوكيات غير المحددة"، ولكن كما أشار آخرون، فإن اللغة الأساسية يمكن التنبؤ بها بشكل كبير عبر الأنظمة الأساسية وإصدارات اللغة وJVM.

هذا لا ينطبق على الرسومات (Swing، AWT)، والتي تميل إلى أن تكون غير متوقعة وليس بالضرورة قابلة للتكرار عبر منصات مختلفة.لقد عملت على تطبيق تصوري يعتمد على لغة Java مكثفًا للرسومات وقضيت الكثير من الوقت في "الكتابة مرة واحدة وتصحيح الأخطاء في كل مكان".

أيضًا، Object.clone() به بعض المشكلات الرئيسية، ولا يُنصح باستخدامه في معظم الحالات.من فضلك راجع البند 11، من "جافا الفعالة" بقلم جوشوا بلوخ للحصول على إجابة كاملة.

هناك نوعان من السلوكيات غير المحددة التي أعرفها:

أ) التحميل الزائد لطريقة بمعلمة تمثل فئة فرعية من نفس المعلمة في الطريقة المحملة بشكل زائد.على سبيل المثال:

void doSomething(Object obj);
void doSomething(String str);

لا توجد طريقة لمعرفة الطريقة التي سيتم استدعاؤها في doSomething("Hello World!")، نظرًا لأن كلا التوقيعين صالحان.كما يمكن أن يتغير هذا السلوك من VM إلى VM، وحتى من تنفيذ إلى تنفيذ.

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

محددة جيدًا ولكنها ليست واضحة:

اختبار كائن للمساواة:

يتم استخدام == لاختبار المراجع (هل يشير مرجعا الكائنين إلى نفس الكائن)

بينما يستخدم يساوي لاختبار المساواة بين الكائنات.

لذلك على سبيل المثال

new String("test") == new String("test")  

غير صحيح، في حين

new String("test").equals( new String("test") )

صحيح

يتم احتجاز كائنات السلسلة بحيث يُرجع ما يلي صحيحًا:

String a = "test";
String b = "test";

a == b  // returns true 

ولكن إذا تم إنشاء السلسلة في مكان آخر (من قاعدة بيانات على سبيل المثال)

String a = "test";
String b = getFromDataBase(); // internally the remote returns "test"

a == b  // returns false.

التحقق من الصحة كاذب.

لقد رأيت هذا يحدث في jsp مع البرامج النصية، ولم يفهم المبرمجون الجدد سبب التحقق من الصحة

 <%if( param == "continue" ) { %>

لا يحدث أبدا

الشيء الوحيد الذي أتذكره هو توافق jvm مع jni.كان لدينا تطبيق تم تطويره على jdk1.4 وعند تثبيته على جهاز مزود بـ ibm jvm (أعتقد ذلك)، تقيأت مكالمة jni للتو!كان ذلك في عام 2006 بالرغم من ذلك.أعتقد أن هذا لا علاقة له بجافا كلغة، ولكن يتعلق أكثر بجافا كمنصة.

يضيف ديناميكية مقابل.ملزمة ثابتة وكيفية تطبيقه ضد الأساليب المثقلة والمتجاوزة ليس واضحا.

ليس غير محدد ولكن السلوك غير المتوقع هو كيفية تقريب الزوجي عند تحويله إلى عدد صحيح.يتم تقريب 0.6d دائمًا إلى 0؛في الواقع، يتم تقريب 0.9d أيضًا إلى 0.لكن 0.99999999999999995 وما فوق سيتم تقريبه إلى 1.

مجرد سلوك مثير للاهتمام عند إرسال نتائج استدعاء Math.random() الذي يجب الحذر منه.

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