النفقات العامة المرتبطة باستثناء مقابل رمي في جافا

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

  •  22-09-2019
  •  | 
  •  

سؤال

أنا أعرف

throw new Exception();

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

throw new Throwable();

تقديم نفس المشكلة؟ هل هذا السلوك ورث ، أم أن رمي رمي يمكن أن يكون له صناديق أصغر (لا)؟

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

public Session newSession() {  
  validate_user_and_password();   
}

إن إلقاء usernotvalidexception قد يبدو صحيحًا من المحللون وجهة نظر.
عودة null أو 0 يبدو فقط غير صحيح إذا كان الكود الخاص بك يحتوي على تجريد جيد. أردت فقط أن أعرف ما إذا كان بإمكاني تنفيذ هذا بالفعل في الكود ، أو إذا كان علي أن أترك الأمر للنظرية.

هناك فرق جيد بين استثناء وجهة نظر البرمجة واستثناء من وجهة نظر المحلل.

ملاحظة: لقد أعطيت مثالًا بسيطًا وسخيفًا حقًا ، فهذا ليس حالتي تمامًا.
الملاحظة 2: أعرف العودة null سيكون الشيء العادي ، لكنني مطالب بالاستخلاص بشكل صحيح ورمز OO ، وأنا شخصياً لا أرى أي ضرر في هذا.

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

المحلول

Throwable يخلق أيضًا stacktrace عند إنشاؤه. من مستندات جافا ل Throwable:

يحتوي Throwable على لقطة من كومة تنفيذ مؤشر ترابطها في الوقت الذي تم إنشاؤه فيه.

لذلك من حيث النفقات العامة فيما يتعلق بإنشاء stacktrace ، يجب ألا يكون هناك فرق بين Exception و Throwable.

إذا كنت تستخدم استثناءات لـ "الأحداث الاستثنائية" (كما يجب أن تكون) ، فلا يجب أن تكون مهتمًا جدًا بالتكاليف من stacktrace. نادرا ما يحدث حدث استثنائي في تشغيل التعليمات البرمجية. لذلك يجب ألا تؤثر الاستثناءات على أداء الكود العادي بأي طريقة مهمة.

نصائح أخرى

كلا ، أنت بحاجة إلى فئة فرعية خاصة بك لتجنب هذا التأثير.

Exception ex = new Exception() {
    @Override public Throwable fillInStackTrace() {
        return this; // and do nothing else
    }
};

هذا ينشئ مثيل استثناء لن يملأ تتبع المكدس (إنشاء مندوبي الاستثناءات fillInStackTrace لملء تتبع المكدس فعليًا) ، وبالتالي فهو رخيص لإنشاء.

مع تجميع JIT ، لا يزال في الواقع هو أن هناك الكثير من سماع رمي Exception في جافا. لكن رمي أ Throwable لا يختلف كثيرًا ، حيث ستحصل على تتبع المكدس هناك أيضًا.

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

يجب ألا ترمي أو تصطاد Throwable. نطاق الاستثناء كبير جدًا.

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

Throwable هي فئة الوالدين من الاستثناء. لذا Exception class ورثت من Throwable.

Throwable vs. Exception

جافا استثناء

كما قال @Mangodrunk: "رمي هو الفئة الفائقة من الاستثناء والخطأ."

يمكنك إلقاء نظرة على الكود المصدري للفئتين لمعرفة ذلك Exception لا تفعل أي شيء يتجاوز فضح نفس البنائين Throwable. كل اللحوم ، وبالتالي النفقات العامة ، تعيش في Throwable.

حتى و إن Exception هل قدمت بعض النفقات العامة الإضافية ، سيكون من الواضح أن الاستخدام Throwable في حين أن. استخدم الأداة المناسبة للوظيفة ، لا تعاون الأداة الخاطئة لمجرد أنها أخف وزنا.

java.lang.Exception يمتد java.lang.Throwable, ، لذلك هو نفس النفقات العامة. من جافادوك:

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

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

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