ในภาษา Java คลาสพื้นฐานของคลาสข้อผิดพลาดคือ java.lang.error และคลาสพื้นฐานของคลาสข้อยกเว้นคือ java.lang.exception
1) ความคล้ายคลึงกัน: java.lang.error และ java.lang.exception เป็นทั้ง subclasses ของ java.lang.hrowable ดังนั้น 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 {โยน 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 จะต้องค้นหารหัส catch Block ที่สามารถจับข้อยกเว้นได้ ก่อนอื่นจะตรวจสอบว่าวิธีการปัจจุบันมีบล็อกรหัสจับหรือไม่และหากมีอยู่ให้ดำเนินการบล็อกรหัสจับหรือไม่ มิฉะนั้น JVM จะกลับไปที่โครงสร้างสแต็กของวิธีการที่สแต็กการโทรและยังคงค้นหาบล็อกรหัสจับที่เหมาะสมในวิธีก่อนหน้า ในที่สุดหาก JVM ไล่ตามวิธีการหลัก () นั่นคือมันจะทำให้การยกเว้นวิธีการหลัก () และยังไม่พบบล็อกโค้ดสำหรับตัวจัดการข้อยกเว้นเธรดจะยุติลงอย่างผิดปกติ หากเธรดเป็นเธรดหลักแอปพลิเคชันจะยุติลงเช่นกัน ในเวลานี้ JVM จะส่งข้อยกเว้นโดยตรงไปยังผู้ใช้และข้อมูลข้อยกเว้นเดิมจะเห็นได้ในเทอร์มินัลผู้ใช้
java.lang. การวิเคราะห์ซอร์สโค้ดที่น่าเชื่อถือ
แพ็คเกจ java.lang; นำเข้า Java.io.*; / ** * * throwable เป็นคลาสหลักของข้อผิดพลาดและข้อยกเว้นทั้งหมด * โปรดทราบว่ามันมีสี่ตัวสร้าง: * throwable () * throwable (ข้อความสตริง) * throwable (throwable cate) * throwable (ข้อความสตริง, สาเหตุที่โยนได้) */ ชั้นเรียนสาธารณะ /*** รหัสดั้งเดิมบันทึกข้อบ่งชี้บางอย่างของสแต็กแบ็คแท็กในช่องนี้ */ Backtrace วัตถุชั่วคราวส่วนตัว; / *** ข้อมูลที่อธิบายข้อยกเว้นนี้*/ รายละเอียดสตริงส่วนตัว; / *** บ่งชี้ว่าข้อยกเว้นปัจจุบันเกิดจากการโยนได้* หากเป็นโมฆะหมายความว่าข้อยกเว้นไม่ได้เกิดจากการโยนที่สามารถโยนได้* หากวัตถุนี้เหมือนกับตัวเองมันบ่งชี้ว่าวัตถุที่ทำให้เกิดข้อยกเว้นไม่ได้เริ่มต้น / *** อาร์เรย์อธิบายแทร็กข้อยกเว้น*/ stacktracelement ส่วนตัว [] stacktrace; / *** ตัวสร้างวัตถุสาเหตุไม่ได้เริ่มต้นสามารถเริ่มต้นได้ในอนาคตโดยใช้ initcause* FillInstackTrace สามารถใช้เพื่อเริ่มต้นอาร์เรย์ของแทร็กข้อยกเว้น*/ public throwable () {FillinstackTrace (); } /*** constructor* /public throwable (ข้อความสตริง) {// เติมอาร์เรย์แทร็กข้อยกเว้น fillinstacktrace (); // เริ่มต้นข้อยกเว้นคำอธิบายข้อมูลรายละเอียด Message = ข้อความ; } / *** constructor สาเหตุแสดงถึงสาเหตุของวัตถุ* / public throwable (ข้อความสตริง, สาเหตุที่โยนได้) {fillinstacktrace (); DetailMessage = ข้อความ; this.cuse = สาเหตุ; } / *** Constructor* / Public Throwable (สาเหตุที่โยนได้) {FillInstackTrace (); DetailMessage = (สาเหตุ == null? null: cause.toString ()); this.cuse = สาเหตุ; } / *** รับข้อมูลรายละเอียด* / สตริงสาธารณะ getMessage () {return detailedMessage; } / *** รับข้อมูลรายละเอียด* / สตริงสาธารณะ getLocalizedMessage () {return getMessage (); } / *** รับวัตถุสาเหตุ* / public throwable getCause () {return (สาเหตุ == สิ่งนี้? null: สาเหตุ); } /*** เริ่มต้นวัตถุสาเหตุ วิธีนี้สามารถเรียกได้เพียงครั้งเดียวโดยไม่ต้องเริ่มต้น*/ การเริ่มต้นที่ได้รับการซิงโครไนซ์สาธารณะ (สาเหตุที่โยนได้) {// ถ้าไม่ใช่สถานะที่ไม่ได้รับการกำหนด // วัตถุสาเหตุที่จะตั้งค่าเท่ากับตัวเองและโยนข้อยกเว้นถ้า (สาเหตุ == สิ่งนี้) โยน unlegalargumentException ใหม่ ("ไม่อนุญาตให้เกิดการเกิดตนเอง"); // ตั้งค่าวัตถุสาเหตุสิ่งนี้สาเหตุ = สาเหตุ; // ส่งคืนสาเหตุที่ตั้งค่าวัตถุส่งคืนสิ่งนี้; } / *** การเป็นตัวแทนสตริง* / สตริงสาธารณะ toString () {string s = getClass (). getName (); ข้อความสตริง = getLocalizedMessage (); return (ข้อความ! = null)? (s + ":" + ข้อความ): s; } / *** พิมพ์แทร็กข้อผิดพลาด* / โมฆะสาธารณะ PrintStackTrace () {printStackTrace (System.err); } /*** พิมพ์ข้อผิดพลาดแทร็ก* /โมฆะสาธารณะ PrintStackTrace (PrintStream S) {ซิงโครไนซ์ (S) {// การเรียกใช้วิธี toString ของวัตถุปัจจุบัน s.println (นี่); // รับอาร์เรย์แทร็กข้อยกเว้น stacktracelement [] trace = getourstacktrace (); // พิมพ์การแสดงสตริงของแต่ละองค์ประกอบสำหรับ (int i = 0; i <trace.length; i ++) s.println ("/tat"+trace [i]); // รับวัตถุสาเหตุที่โยนได้ของเรา = getCause (); // พิมพ์ข้อมูลของวัตถุสาเหตุซ้ำถ้า (Ourcause! = null) Ourcause.printstackTraceascause (s, trace); }} /*** พิมพ์ข้อมูลวัตถุสาเหตุ* @param s สตรีมที่พิมพ์* @param ทำให้แทร็กข้อยกเว้นที่เกิดจากวัตถุนี้เกิดจากวัตถุนี้* /โมฆะส่วนตัว printstackTraceascause (printstream S, stackTraceElement [] ที่เกิดขึ้น) {// รับแทร็กข้อยกเว้นปัจจุบัน // m เป็นองค์ประกอบสุดท้ายของอาร์เรย์แทร็กข้อยกเว้นปัจจุบัน // n เป็นองค์ประกอบสุดท้ายของอาร์เรย์แทร็กข้อยกเว้นของข้อยกเว้นที่เกิดจากวัตถุปัจจุบัน int m = trace.length-1, n = prementtrace.length-1; // วนรอบจากด้านหลังทั้งสองอาร์เรย์ตามลำดับ หากเท่ากันให้วนซ้ำจนกระทั่งความไม่เท่าเทียมกันหรืออาร์เรย์ถึงจุดเริ่มต้นในขณะที่ (m> = 0 && n> = 0 && ติดตาม [m] .equals (ทำให้เกิด [n])) {m--; n--; } // หมายเลขเดียวกัน int framesincommon = trace.length - 1 - m; // พิมพ์ร่องรอยข้อผิดพลาดที่แตกต่างกัน s.println ("เกิดจาก:" + สิ่งนี้); สำหรับ (int i = 0; i <= m; i ++) s.println ("/tat"+trace [i]); // หากมีหมายเลขเดียวกันให้พิมพ์หมายเลขเดียวกันถ้า (framsincommon! = 0) s.println ("/t ... " + framsincommon + "เพิ่มเติม"); // รับสาเหตุของวัตถุนี้และพิมพ์ข้อมูลที่โยนได้ซ้ำได้ของเรา = getCause (); ถ้า (Ourcause! = null) Ourcause.printstackTraceascause (s, trace); } / *** พิมพ์ข้อผิดพลาดแทร็ก* / โมฆะสาธารณะ PrintStackTrace (PrintWriter S) {ซิงโครไนซ์ (S) {S.Println (นี่); stacktraceElement [] trace = getourstacktrace (); สำหรับ (int i = 0; i <trace.length; i ++) s.println ("/tat"+trace [i]); thingable urcause = getCause (); ถ้า (Ourcause! = null) Ourcause.printstackTraceascause (s, trace); }} / *** พิมพ์ข้อมูลเกี่ยวกับวัตถุสาเหตุ* / โมฆะส่วนตัว PrintStackTraCeascause (PrintWriter S, StackTraceElement [] สาเหตุ) {// assert Thread.holdslock; // คำนวณจำนวนเฟรมที่เหมือนกันระหว่างสิ่งนี้และทำให้เกิด stacktracelement [] trace = getourstacktrace (); int m = trace.length-1, n = preatedtrace.length-1; ในขณะที่ (m> = 0 && n> = 0 && trace [m] .equals (ทำให้เกิด [n])) {m--; n--; } int framsincommon = trace.length - 1 - m; s.println ("เกิดจาก:" + สิ่งนี้); สำหรับ (int i = 0; i <= m; i ++) s.println ("/tat"+trace [i]); if (framsincommon! = 0) s.println ("/t ... " + framsincommon + "เพิ่มเติม"); // กลับคืนมาหากเรามีสาเหตุที่ทำให้เกิดขึ้นได้ของเรา = getCause (); ถ้า (Ourcause! = null) Ourcause.printstackTraceascause (s, trace); } / *** กรอกแทร็กข้อยกเว้น* / Public Synchronized Native FillinstackTrace (); / *** ส่งคืนสำเนาของแทร็กข้อยกเว้นปัจจุบัน*/ public stacktraceElement [] getStackTrace () {return (stacktraceElement []) getourStackTrace (). clone (); } /** * รับแทร็กข้อยกเว้นปัจจุบัน * /stackTraceElement แบบซิงโครไนซ์ส่วนตัว [] getourStackTrace () {// ถ้าวิธีนี้เรียกว่าเป็นครั้งแรกอาเรย์แทร็กข้อยกเว้นจะเริ่มต้นถ้า (stacktrace == null) {// รับความลึกระดับความลึก // สร้างอาร์เรย์ใหม่ของแทร็กข้อยกเว้นและเติมมัน stacktrace = new StackTraceElement [ความลึก]; สำหรับ (int i = 0; i <depth; i ++) stacktrace [i] = getStackTraceElement (i); // รับแทร็กข้อยกเว้นของจุดบิตที่ระบุ} return stacktrace; } /*** ตั้งค่าแทร็กข้อยกเว้น* /โมฆะสาธารณะ setStackTrace (stackTraceElement [] stackTrace) {// คัดลอกพารามิเตอร์การตั้งค่า stackTraceElement [] DefendenSiveCopy = (stackTraceElement []) stacktrace.clone (); // ถ้าพารามิเตอร์การตั้งค่ามีองค์ประกอบที่ว่างเปล่าข้อยกเว้นจะถูกโยนลงสำหรับ (int i = 0; i <defensiveCopy.length; i ++) ถ้า (defensiveCopy [i] == null) โยน nullpointerexception ใหม่ ("stacktrace [" + i + "]"); // ตั้งค่าแทร็กข้อยกเว้นของวัตถุปัจจุบัน this.stacktrace = defensiveCopy; } / ** * ความลึกของแทร็กข้อยกเว้น 0 หมายความว่าไม่สามารถรับ * / Native Int Int GetStackTracedEpth (); / *** รับแทร็กข้อยกเว้นของจุดบิตที่ระบุ*/ StackTraceElement ส่วนตัว GetStackTraceElement (INT ดัชนี); Void WriteObject แบบซิงโครไนซ์ส่วนตัว (java.io.ObjectOutputStream S) พ่น IOException {getOrStackTrace (); S.DefaultWriteObject (); -