في لغة Java ، فإن الفئة الأساسية لفئة الخطأ هي java.lang.error ، والفئة الأساسية لفئة الاستثناء هي java.lang.exception.
1) أوجه التشابه: java.lang.error و java.lang.exception كلاهما فئات فرعية من java.lang.Throwable ، لذلك يمكن استخدام java.lang.error و java.lang.exception أنفسهم والفواصل الفرعية الخاصة بهم ككائنات للرمي ، مثل: رمي Myerror () ؛ ورمي myException () جديد ؛ حيث ، فئة myerror هي فئة فرعية من java.lang.error ، وفئة MyException هي فئة فرعية من java.lang.exception.
2) الاختلافات: java.lang.Error نفسها والفئات الفرعية لا تتطلب دعم بيان المحاولة. يمكن إرجاع الطريقة في أي وقت ، كما هو محدد في الطريقة التالية:
السلسلة العامة mymethod () {رمي myerror () جديدة ؛ } حيث فئة myerror هي فئة فرعية من فئة java.lang.error.
تحتاج java.lang.exception نفسها وطباعاتها الفرعية إلى دعم عبارات المحاولة ، وتعريف الطريقة التالية خاطئ:
السلسلة العامة mymethod () {رمي myException () جديدة ؛ }يتم تعريف الطريقة الصحيحة على النحو التالي:
السلسلة العامة mymethod () يلقي myException {رمي new MyException () ؛ }حيث فئة MyException هي فئة فرعية من java.lang.exception.
استثناء Java هو كائن تم إنشاؤه عندما يتم مواجهة موقف غير طبيعي عند تشغيل برنامج Java. يلف معلومات الاستثناء. فئة الجذر لاستثناء Java هي java.lang.Throwable. يحتوي الفصل بأكمله على فئتين فرعيتين مباشرتين java.lang.error و java.lang.exception.error هو خطأ خطير لا يمكن استرداده بواسطة البرنامج نفسه. يشير الاستثناء إلى خطأ استثناء يمكن اكتشافه ومعالجته بواسطة البرنامج. يستخدم JVM مكدس استدعاء الطريقة لتتبع سلسلة من عمليات استدعاء الطريقة في كل مؤشر ترابط ، مما يحفظ المعلومات المحلية لكل طريقة استدعاء. بالنسبة لبرامج Java المستقلة ، يمكن أن تصل إلى الطريقة الرئيسية للبرنامج. عند استدعاء طريقة جديدة ، يضع JVM بنية المكدس التي تصف الطريقة الموجودة في الجزء العلوي من المكدس ، والطريقة الموجودة في الجزء العلوي من المكدس هي طريقة التنفيذ الصحيحة. عندما يتم تنفيذ طريقة J بعد طريقة AVA بشكل طبيعي ، يعود JVM إلى بنية المكدس للطريقة من مكدس الاتصال ، ثم يستمر في معالجة الطريقة السابقة. إذا كانت طريقة Java تلقي استثناءً أثناء تنفيذ الكود ، فيجب على JVM العثور على رمز كتلة الصيد الذي يمكنه التقاط الاستثناء. يتحقق أولاً ما إذا كانت الطريقة الحالية تحتوي على كتلة رمز الصيد ، وإذا كانت موجودة ، قم بتنفيذ كتلة رمز الصيد. خلاف ذلك ، يعود JVM إلى بنية المكدس للطريقة في مكدس الاتصال ، ويستمر في العثور على كتلة رمز الصيد المناسبة في الطريقة السابقة. أخيرًا ، إذا كان JVM يطارد الطريقة الرئيسية () ، فإنه يستمر في إلقاء الاستثناء على الطريقة الرئيسية () ، ولا يزال لم يعثر على كتلة الكود لمعالج الاستثناء ، سينتهي مؤشر الترابط بشكل غير طبيعي. إذا كان الخيط هو الخيط الرئيسي ، فسيتم إنهاء التطبيق أيضًا وفقًا لذلك. في هذا الوقت ، ستقوم JVM بإلقاء الاستثناء مباشرة للمستخدم ، وسيتم رؤية معلومات الاستثناء الأصلية في محطة المستخدم.
java.lang.Throwable تحليل رمز المصدر
حزمة java.lang ؛ استيراد java.io.*؛ / ** * * يمكن رميها هو الفئة الوالدية لجميع الأخطاء والاستثناء * لاحظ أنه يحتوي على أربعة منشئات: * رمي () * رمي (رسالة سلسلة) * قابلة للتخفيف (قابلة للتسمية) * رمي (رسالة سلسلة ، سبب قابلة للتسمية) * */ الطبقة العامة القابلة للتسمية القابلة للتسلسل {private static static ongversionuid = -30426055658047285l ؛ /*** الكود الأصلي يحفظ بعض مؤشرات الظهر المكدس في هذه الفتحة. */ خلفية كائن عابر خاص ؛ / *** المعلومات التي تصف هذا الاستثناء*/ private string detailmessage ؛ / *** يشير إلى أن الاستثناء الحالي ناتج عن الرمي* إذا كان NULL يعني أن الاستثناء غير قابل للارتفاع* إذا كان هذا الكائن هو نفسه كما هو الحال ، فهو يشير إلى أن الكائن الذي يسبب الاستثناء لم يتم تهيئته*/ سبب رمي خاص = هذا ؛ / *** صفيف يصف مسار الاستثناء*/ stackTraceElement الخاص [] stacktrace ؛ / *** مُنشئ ، يمكن تهيئة كائن السبب في المستقبل في المستقبل باستخدام initcause* fillInstackTrace لتهيئة مجموعة من مسارات الاستثناء*/ publicable () {fillInstackTrace () ؛ } /*** Constructor* /publicable (رسالة سلسلة) {// املأ استثناء Array Array FillInstackTrace () ؛ // تهيئة استثناء وصف تفاصيل المعلومات = رسالة ؛ } / *** مُنشئ ، يمثل السبب كائن السبب* / رمي عام (رسالة سلسلة ، سبب قابل للارتناء) {fillInStackTrace () ؛ التفاصيل = رسالة ؛ this.cause = السبب ؛ } / *** constructor* / publicable (قابلية للتسمية) {fillInStackTrace () ؛ التفاصيل = (السبب == null؟ null: cause.toString ()) ؛ this.cause = السبب ؛ } / *** احصل على معلومات مفصلة* / سلسلة عامة getMessage () {return calfedMessage ؛ } / *** احصل على معلومات مفصلة* / سلسلة عامة getLocalizedMessage () {return getMessage () ؛ } / *** احصل على كائن السبب* / getCause القابل للإسقاط العام () {return (cause == this؟ null: cause) ؛ } /*** تهيئة كائن السبب. لا يمكن استدعاء هذه الطريقة إلا مرة واحدة دون التهيئة*/ بدء الرمي المزامنة العامة (سبب رمي) {// إذا لم تكن حالة غير مؤهلة ، رمي استثناءً إذا (هذا. . // قم بتعيين كائن السبب this.cause = cause ؛ // إرجاع كائن cause set إرجاع هذا ؛ } / *** تمثيل السلسلة* / السلسلة العامة toString () {string s = getClass (). getName () ؛ رسالة سلسلة = getLocalizedMessage () ؛ العودة (الرسالة! = فارغة)؟ (S + ":" + رسالة): s ؛ } / *** طباعة مسار الخطأ* / public void printStackTrace () {printStackTrace (System.err) ؛ } /*** طباعة مسار الخطأ* /public void printstacktrace (printstream s) {synchronized (s) {// استدعاء طريقة toString للكائن الحالي s.println (this) ؛ // احصل على استثناء Track Array StackTraceElement [] Trace = getourstacktrace () ؛ // اطبع تمثيل السلسلة لكل عنصر لـ (int i = 0 ؛ i <trace.length ؛ i ++) s.println ("/tat"+trace [i]) ؛ // احصل على كائن السبب القابل للتسمية ourcause = getCause () ؛ // بطباعة معلومات كائن السبب بشكل متكرر إذا (ourcause! = null) urcause.printstacktraceascause (s ، trace) ؛ }} /*** اطبع معلومات كائن السبب* param s تدفق مطبوع* param quateTrace استثناء مع استثناء ناتج عن هذا الكائن* /private void printStackTraceAscause (printstream s ، stacktraceElement [] quateTrace) {// الحصول على استثناء الحالي stackTraceElement [] trace = getourstacktrace () ؛ . // حلقة من وراء المصفمين على التوالي. إذا كان ذلك متساويًا ، فإن حلقة حتى عدم المساواة أو الصفيف تصل إلى البداية (m> = 0 && n> = 0 && trace [m] .equals (QuateTrace [n])) {m-- ؛ ن-- ؛ } // نفس الرقم int framesincommon = trace.length - 1 - m ؛ // طباعة أخطاء مختلفة آثار s.println ("سبب:" + هذا) ؛ لـ (int i = 0 ؛ i <= m ؛ i ++) s.println ("/tat"+trace [i]) ؛ // إذا كان هناك نفس الرقم ، فقم بطباعة نفس الرقم إذا (FramesIncommon! = 0) // احصل على سبب هذا الكائن وطباعة المعلومات القابلة للتراجع عن urcause = getCause () ؛ if (ourCause! = null) ourCause.printStackTraceAscause (s ، trace) ؛ } / *** طباعة مسار الخطأ* / public void printstacktrace (printWriter s) {synchronized (s) {s.println (this) ؛ StackTraceElement [] trace = getourstacktrace () ؛ لـ (int i = 0 ؛ i <trace.length ؛ i ++) s.println ("/tat"+trace [i]) ؛ رمي OurCause = getCause () ؛ if (ourCause! = null) ourCause.printStackTraceAscause (s ، trace) ؛ }} / *** طباعة المعلومات حول كائن السبب* / private void printstacktraceascause (printWriter S ، stackTraceElement [] QuateTrace) {// assert thread.holdslock (s) ؛ // حساب عدد الإطارات المشتركة بين هذا وتسبب في تتبع stackTraceElement [] = getourstacktrace () ؛ int m = trace.length-1 ، n = quateTrace.Length-1 ؛ بينما (m> = 0 && n> = 0 && trace [m] .equals (QuateTrace [n])) {m-- ؛ ن-- ؛ } int framesincommon = trace.length - 1 - m ؛ S.Println ("سبب:" + هذا) ؛ لـ (int i = 0 ؛ i <= m ؛ i ++) s.println ("/tat"+trace [i]) ؛ if (framesincommon! = 0) // Recurse إذا كان لدينا سبب يمكن رميها urcauses = getCause () ؛ if (ourCause! = null) ourCause.printStackTraceAscause (s ، trace) ؛ } / *** املأ مسار الاستثناء* / FillInstackTrace المتواصل الأصلي المزامن () ؛ / *** إرجاع نسخة من مسار الاستثناء الحالي*/ public StackTraceElement [] getStackTrace () {return (stackTraceElement []) getourstacktrace (). clone () ؛ } /** * احصل على مسار الاستثناء الحالي * /stackTraceElement المزامنة الخاصة [] getourstacktrace () {// إذا تم استدعاء هذه الطريقة لأول مرة ، يتم تهيئة صفيف تتبع الاستثناء if (stackTrace == null) {// الحصول على عمق التتبع int depth = getStackTracedepth () ؛ // قم بإنشاء مجموعة جديدة من مسارات الاستثناء واملأها stacktrace = stackTraceElement جديد [Depth] ؛ لـ (int i = 0 ؛ i <depth ؛ i ++) stacktrace [i] = getStackTraceElement (i) ؛ // احصل على مسار استثناء نقطة البت المحددة} stacktrace ؛ } /*** تعيين Track Track* /public void setStackTrace (StackTraceElement [] stacktrace) {// انسخ المعلمة الإعداد StackTraceElement [] DefendenSivecopy = (StackTraceElement []) stacktrace.clone () ؛ // إذا كانت المعلمة الإعداد تحتوي على عناصر فارغة ، فسيتم طرح استثناء (int i = 0 ؛ i <defensivecopy.length ؛ i ++) إذا (defensivecopy [i] == null) رمي nullpointerxception ("stacktrace [" + i + "]" // قم بتعيين تتبع استثناء الكائن الحالي this.stacktrace = defensivecopy ؛ } / ** * عمق مسار الاستثناء ، 0 يعني أنه من غير الممكن الحصول على * / private native int getStackTracedEpth () ؛ / *** احصل على مسار الاستثناء لنقطة البتات المحددة*/ private stacktraceElement getStackTraceElement (int index) ؛ private synchroned void writeObject (java.io.ObjectOutputStream s) رمي ioException {getourstacktrace () ؛ S.DefaultWriteObject () ؛ }}