متى يجب استخدام Throwable بدلاً من الاستثناء الجديد؟

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

  •  20-08-2019
  •  | 
  •  

سؤال

منح: Throwable يكون Exceptionالطبقة المتفوقة.

عندما أقرأ نصوصًا عن كتابة "الاستثناءات" الخاصة بك، أرى أمثلة عليها Throwable المستخدمة في catch تظهر الكتلة والنصوص الأخرى new Exception() المستخدمة في catch حاجز.لم أر بعد شرحًا للوقت الذي يجب فيه استخدام كل منهما.

سؤالي هو هذا، متى ينبغي ذلك Throwable استخدامها ومتى ينبغي new Exception() يستخدم؟

داخل catch أو else الحظر باستخدام إما:

throw throwable;

أو

throw new Exception();
هل كانت مفيدة؟

المحلول

<اقتباس فقرة>   

و(من تعليق) المشكلة التي جلبت هذا الأمر هو أن   ولست بحاجة لتمرير "استثناء" ل   قطعة من رمز هو بناء زميل العمل   إذا كان جمع لا يحصل بناؤها.

في هذه الحالة، قد ترغب في رمي <م> تحديد استثناء . هل يمكن رمي Exception ، وهو مناسب الحالية فرعية منه (باستثناء RuntimeException والفئات الفرعية التي هي <م> لحالها )، أو فئة فرعية مخصصة من Exception (على سبيل المثال "CollectionBuildException"). انظر جافا البرنامج التعليمي على الاستثناءات للحصول على ما يصل الى سرعة مع استثناءات جافا.

نصائح أخرى

ورمي دائما على Exception (أبدا Throwable). أنت عموما لا يمسك Throwable سواء، ولكن يمكنك. قابل للظهور هي المتفوقة لException وError، لذلك كنت قبض Throwable إذا أردت أن يمسك Exceptions لكن Errors ليس فقط، وهذا هو بيت القصيد في وجود لها. الشيء هو، Errors عادة ما تكون الأشياء التي من شأنها ولا ينبغي قبض على التطبيق العادي، لذلك مجرد استخدام Exception لم يكن لديك سبب محدد لاستخدام Throwable.

ويجب أن لا يمسك حقا استثناء ورمي واحد جديد في عام باسم "استثناء الجديد".

وبدلا من ذلك، إذا كنت ترغب في فقاعة يصل باستثناء تفعل ما يلي:

try {
    // Do some stuff here
}
catch (DivideByZeroException e) {
    System.out.println("Can't divide by Zero!"); 
} 
catch (IndexOutOfRangeException e) { 
    // catch the exception 
    System.out.println("No matching element found.");
}
catch (Throwable e) {
    throw e; // rethrow the exception/error that occurred
}

وليس من الممارسات الجيدة، على ما أعتقد، لجذب استثناء ورمي استثناء جديد بدلا من تلك التي أثيرت في كتلة التعليمات البرمجية الخاصة بك، إلا إذا رفع استثناء مخصصة مفيد يوفر السياق يكفي أن يتملص من أجل قضية باستثناء الأصلي.

ومكانين فقط سترى Throwable كلمة في التعليمات البرمجية:

public static void main(String args[])
{
     try
     {
         // Do some stuff
     }
     catch(Throwable t)
     {

     }
 }

و

public class SomeServlet extends HttpServlet
{
      public void doPost(HttpRequest request, HttpResponse response)
      {
         try
         {
             // Do some stuff
         }
         catch (Throwable t)
         {
              // Log
         }
      }
 }

<الإضراب> قابل للظهور هي واجهة، وليس فئة. فئتين تمتد قابل للظهور، واستثناء خطأ.

والقاعدة هي: أن تكون محددة كما يمكنك عند اصطياد استثناءات - وهذا يعني على سبيل المثال اصطياد استثناء بدلا من قابل للظهور، وIOException بدلا من استثناء

.

ولا يمسك أخطاء - الأخطاء هي أخطاء. إصلاح رمز بدلا من ذلك.

إذا كان لديك للقبض على كل شيء، استخدم "قبض قابل للظهور"، ولكن هذا هو شكل سيء.

وthrow new Exception(); شيء يجب عليك <م> لا القيام به في كتلة الصيد، ولكن قد تضطر إلى أو تريد أن تفعل new SomeException(throwable); رمي (الحفاظ على تتبع مكدس الكامل) بدلا من throw throwable; لتتوافق مع API طريقة الخاص بك، على سبيل المثال عندما يعلن لرمي SomeException ولكن كنت استدعاء التعليمات البرمجية التي قد رمي IOException أن كنت لا تريد أن تضيف إلى بند throws لك طريقة ل.

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

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

وحتى مجرد التقاط استثناء (أو الأفضل من ذلك، استثناء أكثر غرامة الحبيبات).

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

وجميع الاستثناءات هي مشكلة في النهاية ... ويقول أيضا أخطاء هي البق لا يعني أي شيء.

وأخطاء ليست البق - فهي المشاكل التي المضيف VM تشهد، على سبيل المثال OutOfMemoryError. الاستثناءات هي وسيلة أن العملية الحالية قد تستخدم لإعلام أنه فشل وربما توفير بعض التشخيص.

وعموما، فإنك لن رمي أو قبض قابل للظهور. على وجه الخصوص، أخطاء JVM (التي تمتد خطأ ()) لا <م> يعني أن تكون اشتعلت من قبل رمز المستخدم إلا إذا كنت تقوم بعمل غريب على مستوى النظام.

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

وهذا يشمل كلا من حالات الخطأ العادية (عن طريق "العادية" أعني على العكس من الأخطاء JVM) والأماكن التي تستخدم استثناءات كآلية السيطرة.

لا يجب عليك استخدام الاستثناءات كـ "نوع إرجاع" أيضًا ...

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

لقد رأيت حالات حيث ألقت الحلقات الضيقة الاستثناءات باعتبارها "سلبية" على سبيل المثال.تخصيص المعرف، هذا الروتين يشغل حوالي 99% من وقت وحدة المعالجة المركزية.وعندما تم تغييره إلى ثابت إرجاع موثق بدلاً من ذلك، انخفض هذا إلى 25%.

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