เหตุใด exception.printStackTrace () จึงถือว่าเป็นการปฏิบัติที่ไม่ดี


127

มีเป็นจำนวนมากของวัสดุออกมีซึ่งแสดงให้เห็นว่าการพิมพ์ร่องรอยสแต็คของข้อยกเว้นคือการปฏิบัติที่ไม่ดี

เช่นจากการตรวจสอบ RegexpSingleline ใน Checkstyle:

การตรวจสอบนี้สามารถใช้ [... ] เพื่อค้นหาแนวปฏิบัติที่ไม่ดีทั่วไปเช่นการเรียก ex.printStacktrace ()

อย่างไรก็ตามฉันกำลังดิ้นรนเพื่อค้นหาทุกที่ที่ให้เหตุผลที่ถูกต้องว่าทำไมการติดตามสแต็กจึงมีประโยชน์มากในการติดตามสิ่งที่ทำให้เกิดข้อยกเว้น สิ่งที่ฉันทราบ:

  1. ผู้ใช้ปลายทางไม่ควรมองเห็นสแต็กแทร็ก (สำหรับประสบการณ์ของผู้ใช้และวัตถุประสงค์ด้านความปลอดภัย)

  2. การสร้างสแต็กแทร็กเป็นกระบวนการที่ค่อนข้างแพง (แม้ว่าจะไม่น่าจะเป็นปัญหาในสถานการณ์ 'พิเศษ' ส่วนใหญ่)

  3. เฟรมเวิร์กการบันทึกจำนวนมากจะพิมพ์การติดตามสแต็กให้คุณ (ของเราไม่ทำและไม่เปลี่ยนไม่ได้ง่ายๆ)

  4. การพิมพ์การติดตามสแต็กไม่ถือเป็นการจัดการข้อผิดพลาด ควรใช้ร่วมกับการบันทึกข้อมูลอื่น ๆ และการจัดการข้อยกเว้น

มีเหตุผลอะไรอีกบ้างที่หลีกเลี่ยงการพิมพ์สแต็กแทร็กในโค้ดของคุณ


12
ในฐานะคนที่ต้องแก้ไขปัญหาเป็นประจำฉันจะไม่ละเว้นการพิมพ์ stacktrace เมื่อมีสิ่งผิดปกติเกิดขึ้น ใช่ไม่ต้องแสดงให้ผู้ใช้เห็น แต่ใช่ให้ถ่ายโอนข้อมูลไปยังบันทึกข้อผิดพลาด
Paul Grime

4
คุณต้องการเหตุผลอื่นหรือไม่? ฉันคิดว่าคุณตอบคำถามของตัวเองได้ดีพอสมควร อย่างไรก็ตามควรพิมพ์ stacktrace ในข้อยกเว้นพิเศษ :)
Neil

คำตอบ:


125

Throwable.printStackTrace()เขียนการติดตามสแต็กไปยังSystem.errPrintStream System.errกระแสและอยู่ภายใต้มาตรฐาน "ข้อผิดพลาด" กระแสออกของกระบวนการ JVM สามารถเปลี่ยนเส้นทางโดย

  • กล่าวอ้างซึ่งการเปลี่ยนแปลงปลายทางที่ชี้ไปตามSystem.setErr()System.err
  • หรือโดยการเปลี่ยนเส้นทางสตรีมเอาต์พุตข้อผิดพลาดของกระบวนการ สตรีมเอาต์พุตข้อผิดพลาดอาจถูกเปลี่ยนเส้นทางไปยังไฟล์ / อุปกรณ์
    • ซึ่งบุคลากรอาจละเลยเนื้อหา
    • ไฟล์ / อุปกรณ์อาจไม่สามารถล็อกการหมุนได้โดยอนุมานว่าต้องมีการรีสตาร์ทกระบวนการเพื่อปิดที่จับไฟล์ / อุปกรณ์ที่เปิดก่อนที่จะเก็บถาวรเนื้อหาที่มีอยู่ของไฟล์ / อุปกรณ์
    • หรือไฟล์ / /dev/nullอุปกรณ์จริงทิ้งข้อมูลทั้งหมดที่เขียนให้มันเป็นกรณีของ

การอ้างถึงจากข้างต้นการเรียกใช้Throwable.printStackTrace()ถือเป็นพฤติกรรมการจัดการข้อยกเว้นที่ถูกต้อง (ไม่ดี / ดีมาก) เท่านั้น

  • หากคุณไม่ได้System.errรับการกำหนดใหม่ตลอดช่วงอายุการใช้งานของแอปพลิเคชัน
  • และหากคุณไม่ต้องการการหมุนเวียนบันทึกในขณะที่แอปพลิเคชันกำลังทำงานอยู่
  • และหากได้รับการยอมรับ / ออกแบบวิธีการบันทึกของแอปพลิเคชันคือการเขียนถึงSystem.err(และสตรีมเอาต์พุตข้อผิดพลาดมาตรฐานของ JVM)

ในกรณีส่วนใหญ่ไม่พอใจเงื่อนไขข้างต้น อาจไม่ทราบถึงรหัสอื่น ๆ ที่ทำงานใน JVM และไม่สามารถคาดเดาขนาดของไฟล์บันทึกหรือระยะเวลารันไทม์ของกระบวนการได้และแนวทางปฏิบัติในการบันทึกที่ออกแบบมาอย่างดีจะวนเวียนอยู่กับการเขียนไฟล์บันทึกแบบ "แยกวิเคราะห์โดยเครื่อง" (a คุณสมบัติที่ดีกว่า แต่เป็นทางเลือกในเครื่องตัดไม้) ในปลายทางที่รู้จักเพื่อช่วยในการสนับสนุน

ในที่สุดเราควรจำไว้ว่าผลลัพธ์ของThrowable.printStackTrace()จะถูกแทรกเข้าด้วยกันอย่างแน่นอนกับเนื้อหาอื่น ๆ ที่เขียนถึงSystem.err(และอาจเป็นไปได้System.outว่าทั้งคู่จะถูกเปลี่ยนเส้นทางไปยังไฟล์ / อุปกรณ์เดียวกัน) นี่เป็นสิ่งที่น่ารำคาญ (สำหรับแอพแบบเธรดเดียว) ที่เราต้องจัดการเนื่องจากข้อมูลเกี่ยวกับข้อยกเว้นนั้นไม่สามารถแยกวิเคราะห์ได้อย่างง่ายดายในเหตุการณ์ดังกล่าว ที่แย่กว่านั้นมีความเป็นไปได้สูงที่แอปพลิเคชันแบบมัลติเธรดจะสร้างบันทึกที่สับสนมากเนื่องจากThrowable.printStackTrace() ไม่ปลอดภัยต่อเธรด

ไม่มีกลไกการซิงโครไนซ์เพื่อซิงโครไนซ์การเขียนการติดตามสแต็กSystem.errเมื่อหลายเธรดเรียกใช้Throwable.printStackTrace()ในเวลาเดียวกัน การแก้ปัญหานี้ต้องใช้รหัสของคุณในการซิงโครไนซ์บนจอภาพที่เกี่ยวข้องSystem.err(และSystem.outหากไฟล์ / อุปกรณ์ปลายทางเหมือนกัน) และนั่นเป็นราคาที่ค่อนข้างหนักในการจ่ายเพื่อความปลอดภัยของไฟล์บันทึก เพื่อที่จะใช้ตัวอย่างที่ConsoleHandlerและStreamHandlerการเรียนมีความรับผิดชอบในการผนวกบันทึกเข้าสู่ระบบไปยังคอนโซลในการเข้าสู่ระบบสิ่งอำนวยความสะดวกที่มีให้โดยjava.util.logging; การดำเนินการจริงของการเผยแพร่บันทึกบันทึกจะซิงโครไนซ์ - ทุกเธรดที่พยายามเผยแพร่บันทึกบันทึกจะต้องได้รับการล็อกบนจอภาพที่เกี่ยวข้องกับStreamHandlerตัวอย่าง. หากคุณต้องการรับประกันแบบเดียวกันว่าจะมีบันทึกการบันทึกแบบไม่แทรกสลับโดยใช้System.out/ System.errคุณต้องแน่ใจว่าเหมือนกัน - ข้อความจะถูกเผยแพร่ไปยังสตรีมเหล่านี้ในลักษณะที่ต่อเนื่องกันได้

เมื่อพิจารณาจากทั้งหมดข้างต้นและสถานการณ์ที่มีข้อ จำกัด ซึ่งThrowable.printStackTrace()เป็นประโยชน์จริงมักจะพบว่าการกล่าวอ้างเป็นแนวทางปฏิบัติที่ไม่ดี


การขยายอาร์กิวเมนต์ในหนึ่งในย่อหน้าก่อนหน้านี้ยังเป็นตัวเลือกที่ไม่ดีที่จะใช้Throwable.printStackTraceร่วมกับคนตัดไม้ที่เขียนลงในคอนโซล นี่เป็นส่วนหนึ่งเนื่องจากสาเหตุที่คนตัดไม้จะซิงโครไนซ์บนจอภาพอื่นในขณะที่แอปพลิเคชันของคุณ (อาจเป็นไปได้ว่าคุณไม่ต้องการให้บันทึกการบันทึกแบบสอดแทรก) ซิงโครไนซ์บนจอภาพอื่น อาร์กิวเมนต์นี้ยังเป็นประโยชน์เมื่อคุณใช้คนตัดไม้สองคนที่เขียนถึงปลายทางเดียวกันในแอปพลิเคชันของคุณ


คำตอบที่ดีขอบคุณ อย่างไรก็ตามในขณะที่ฉันยอมรับว่าเวลาส่วนใหญ่มีเสียงดังหรือไม่จำเป็น แต่ก็มีช่วงเวลาที่วิกฤตอย่างยิ่ง
Chris Knight

1
@ Chris ใช่มีบางครั้งเมื่อคุณไม่สามารถ แต่ใช้System.out.printlnและThrowable.printStackTraceและแน่นอนการตัดสินนักพัฒนาซอฟต์แวร์ ฉันค่อนข้างกังวลว่าส่วนที่เกี่ยวกับความปลอดภัยของเธรดนั้นพลาดไป ถ้าคุณดูที่การใช้งานมากที่สุดคนตัดไม้ที่คุณจะสังเกตเห็นว่าพวกเขาประสานส่วนหนึ่งที่บันทึกเข้าสู่ระบบจะถูกเขียน (แม้ยังคอนโซล) แม้ว่าพวกเขาจะไม่ได้รับการตรวจสอบบนหรือSystem.err System.out
Vineet Reynolds

2
ฉันคิดผิดไหมที่จะทราบว่าไม่มีเหตุผลเหล่านี้ใช้กับการแทนที่ printStackTrace ที่ใช้วัตถุ PrintStream หรือ PrintWriter เป็นพารามิเตอร์
ESRogs

1
@ Geek ตัวหลังเป็นตัวบอกไฟล์กระบวนการที่มีค่า 2 อดีตเป็นเพียงนามธรรม
Vineet Reynolds

1
ในซอร์สโค้ด JDK ของ printStackTrace () จะใช้การซิงโครไนซ์เพื่อล็อค System.err PrintStream ดังนั้นจึงควรเป็นวิธีที่ปลอดภัยสำหรับเธรด
EyouGo

33

คุณกำลังพบปัญหามากมายที่นี่:

1) การติดตามสแต็กไม่ควรเปิดเผยต่อผู้ใช้ปลายทาง (เพื่อประสบการณ์ของผู้ใช้และวัตถุประสงค์ด้านความปลอดภัย)

ใช่ควรสามารถเข้าถึงได้เพื่อวินิจฉัยปัญหาของผู้ใช้ปลายทาง แต่ผู้ใช้ปลายทางไม่ควรเห็นปัญหาด้วยเหตุผลสองประการ:

  • พวกมันคลุมเครือและไม่สามารถอ่านได้แอปพลิเคชั่นจะดูไม่เป็นมิตรกับผู้ใช้
  • การแสดงการติดตามสแต็กแก่ผู้ใช้ปลายทางอาจทำให้เกิดความเสี่ยงด้านความปลอดภัย แก้ไขฉันถ้าฉันผิดจริง PHP พิมพ์พารามิเตอร์ฟังก์ชันในการติดตามสแต็ก - ยอดเยี่ยม แต่อันตรายมาก - หากคุณได้รับข้อยกเว้นขณะเชื่อมต่อกับฐานข้อมูลคุณมีแนวโน้มที่จะทำอะไรใน stacktrace?

2) การสร้างสแต็กแทร็กเป็นกระบวนการที่ค่อนข้างแพง (แม้ว่าจะไม่น่าจะเป็นปัญหาในสถานการณ์ 'ข้อยกเว้น' ส่วนใหญ่)

การสร้างการติดตามสแต็กจะเกิดขึ้นเมื่อมีการสร้าง / โยนข้อยกเว้น (นั่นคือเหตุผลที่การโยนข้อยกเว้นมาพร้อมกับราคา) การพิมพ์จึงไม่แพง ในความเป็นจริงคุณสามารถลบล้างThrowable#fillInStackTrace()ข้อยกเว้นที่กำหนดเองของคุณได้อย่างมีประสิทธิภาพทำให้การโยนข้อยกเว้นเกือบถูกพอ ๆ กับคำสั่ง GOTO ธรรมดา ๆ

3) เฟรมเวิร์กการบันทึกจำนวนมากจะพิมพ์การติดตามสแต็กให้คุณ (ของเราไม่ทำและไม่เปลี่ยนไม่ได้ง่ายๆ)

จุดที่ดีมาก ปัญหาหลักที่นี่คือ: หากเฟรมเวิร์กบันทึกข้อยกเว้นให้คุณอย่าทำอะไรเลย (แต่ตรวจสอบให้แน่ใจ!) หากคุณต้องการบันทึกข้อยกเว้นด้วยตัวเองให้ใช้กรอบการบันทึกเช่นLogbackหรือLog4Jเพื่อไม่วางไว้บนคอนโซลดิบ เพราะมันยากมากที่จะควบคุมมัน

ด้วยกรอบการบันทึกคุณสามารถเปลี่ยนเส้นทางสแต็กเทรซไปยังไฟล์คอนโซลหรือแม้กระทั่งส่งไปยังที่อยู่อีเมลที่ระบุ ด้วยฮาร์ดโค้ดprintStackTrace()คุณจะต้องอยู่กับsysout.

4) การพิมพ์การติดตามสแต็กไม่ถือเป็นการจัดการข้อผิดพลาด ควรใช้ร่วมกับการบันทึกข้อมูลอื่น ๆ และการจัดการข้อยกเว้น

อีกครั้ง: เข้าสู่ระบบSQLExceptionอย่างถูกต้อง (ด้วยการติดตามสแต็กแบบเต็มโดยใช้กรอบการบันทึก) และแสดงข้อความ " ขออภัยขณะนี้เราไม่สามารถดำเนินการตามคำขอของคุณได้ " คุณคิดว่าผู้ใช้สนใจเหตุผลจริงๆหรือไม่? คุณเคยเห็นหน้าจอข้อผิดพลาด StackOverflow หรือไม่? เป็นเรื่องตลกมาก แต่ไม่เปิดเผยรายละเอียดใด ๆ อย่างไรก็ตามจะทำให้ผู้ใช้มั่นใจได้ว่าปัญหาจะได้รับการตรวจสอบ

แต่เขาจะโทรหาคุณทันทีและคุณต้องสามารถวินิจฉัยปัญหาได้ ดังนั้นคุณต้องมีทั้งสองอย่าง: การบันทึกข้อยกเว้นที่เหมาะสมและข้อความที่ใช้งานง่าย


ในการสรุปสิ่งต่างๆ: บันทึกข้อยกเว้นเสมอ (ควรใช้กรอบการบันทึก ) แต่อย่าให้ผู้ใช้ปลายทางเห็น คิดอย่างรอบคอบและเกี่ยวกับข้อความแสดงข้อผิดพลาดใน GUI ของคุณแสดงสแต็กเทรซในโหมดการพัฒนาเท่านั้น


คำตอบของคุณคือสิ่งที่ฉันได้รับ
Blasanka

"สถานการณ์ยกเว้น" ส่วนใหญ่ ดี
awwsmm

19

สิ่งแรกprintStackTrace ()ไม่แพงอย่างที่คุณระบุเนื่องจากการติดตามสแต็กถูกเติมเต็มเมื่อสร้างข้อยกเว้นขึ้นเอง

แนวคิดคือการส่งสิ่งใดก็ตามที่ไปยังบันทึกผ่านเฟรมเวิร์กคนตัดไม้เพื่อให้สามารถควบคุมการบันทึกได้ ดังนั้นแทนที่จะใช้ printStackTrace ให้ใช้สิ่งที่ต้องการLogger.log(msg, exception);


11

การพิมพ์การติดตามสแต็กของข้อยกเว้นในตัวเองไม่ได้ถือเป็นการปฏิบัติที่ไม่ดี แต่การพิมพ์การติดตามสเตซเมื่อเกิดข้อยกเว้นอาจเป็นปัญหาที่นี่บ่อยครั้งเพียงแค่การพิมพ์สแต็กแทร็กเท่านั้นไม่เพียงพอ

นอกจากนี้ยังมีแนวโน้มที่จะสงสัยว่าจะไม่มีการจัดการข้อยกเว้นที่เหมาะสมหากดำเนินการทั้งหมดในcatchบล็อกเป็นไฟล์e.printStackTrace. การจัดการที่ไม่เหมาะสมอาจหมายถึงปัญหาที่ดีที่สุดกำลังถูกละเลยและที่แย่ที่สุดคือโปรแกรมที่ยังคงดำเนินการต่อไปในสถานะที่ไม่ได้กำหนดหรือไม่คาดคิด

ตัวอย่าง

ลองพิจารณาตัวอย่างต่อไปนี้:

try {
  initializeState();

} catch (TheSkyIsFallingEndOfTheWorldException e) {
  e.printStackTrace();
}

continueProcessingAssumingThatTheStateIsCorrect();

ที่นี่เราต้องการดำเนินการเริ่มต้นบางอย่างก่อนที่เราจะดำเนินการต่อไปยังการประมวลผลบางอย่างที่จำเป็นต้องมีการเริ่มต้น

ในโค้ดด้านบนข้อยกเว้นควรได้รับการตรวจจับและจัดการอย่างเหมาะสมเพื่อป้องกันไม่ให้โปรแกรมดำเนินการตามcontinueProcessingAssumingThatTheStateIsCorrectวิธีการที่เราคิดว่าอาจทำให้เกิดปัญหาได้

ในหลาย ๆ กรณีe.printStackTrace()เป็นข้อบ่งชี้ว่ามีการกลืนข้อยกเว้นบางอย่างและการประมวลผลได้รับอนุญาตให้ดำเนินการต่อราวกับว่าไม่มีปัญหาใด ๆ เกิดขึ้น

เหตุใดจึงกลายเป็นปัญหา

อาจเป็นหนึ่งในเหตุผลที่ใหญ่ที่สุดที่ทำให้การจัดการข้อยกเว้นที่ไม่ดีเป็นที่แพร่หลายมากขึ้นเนื่องจาก IDE เช่น Eclipse จะสร้างโค้ดอัตโนมัติที่จะดำเนินการe.printStackTraceสำหรับการจัดการข้อยกเว้น:

try {
  Thread.sleep(1000);
} catch (InterruptedException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
}

(ด้านบนนี้เป็นสิ่งที่try-catchEclipse สร้างขึ้นโดยอัตโนมัติเพื่อจัดการกับการInterruptedExceptionโยนเข้าThread.sleepมา)

สำหรับแอพพลิเคชั่นส่วนใหญ่การพิมพ์การติดตามสแต็กเป็นข้อผิดพลาดมาตรฐานอาจไม่เพียงพอ การจัดการข้อยกเว้นที่ไม่เหมาะสมในหลาย ๆ กรณีอาจทำให้แอปพลิเคชันทำงานในสถานะที่ไม่คาดคิดและอาจนำไปสู่พฤติกรรมที่ไม่คาดคิดและไม่ได้กำหนด


1
นี้. บ่อยครั้งที่การไม่จับข้อยกเว้นเลยอย่างน้อยก็ในระดับวิธีการจะดีกว่าการจับพิมพ์การติดตามสแต็กและดำเนินการต่อราวกับว่าไม่มีปัญหาเกิดขึ้น
EIS

10

ฉันคิดว่ารายการเหตุผลของคุณค่อนข้างครอบคลุม

ตัวอย่างที่ไม่ดีอย่างยิ่งอย่างหนึ่งที่ฉันพบมากกว่าหนึ่งครั้งเป็นเช่นนี้:

    try {
      // do stuff
    } catch (Exception e) {
        e.printStackTrace(); // and swallow the exception
    }

ปัญหากับโค้ดข้างต้นก็คือว่าการจัดการประกอบด้วยทั้งหมดของprintStackTraceโทร: ข้อยกเว้นที่ไม่ได้รับการจัดการอย่างถูกต้องจริงๆไม่เป็นมันได้รับอนุญาตที่จะหลบหนี

ในทางกลับกันตามกฎแล้วฉันมักจะบันทึกการติดตามสแต็กทุกครั้งที่มีข้อยกเว้นที่ไม่คาดคิดในโค้ดของฉัน ในช่วงหลายปีที่ผ่านมานโยบายนี้ช่วยให้ฉันประหยัดเวลาในการแก้ไขข้อบกพร่องได้มาก

ในที่สุดเมื่อทราบเบาของพระเจ้าที่สมบูรณ์แบบข้อยกเว้น


"ข้อยกเว้นไม่ได้รับอนุญาตให้หลีกเลี่ยง" - คุณหมายความว่าข้อยกเว้นถูกแพร่กระจายไปยังสแต็กหรือไม่? การบันทึกต่างจาก printStackTrace () อย่างไร?
MasterJoe

5

printStackTrace()พิมพ์ไปยังคอนโซล ในการตั้งค่าการผลิตไม่มีใครเฝ้าดูเลย Suraj ถูกต้องควรส่งข้อมูลนี้ให้คนตัดไม้


จุดที่ถูกต้องแม้ว่าเราจะดูเอาต์พุตคอนโซลการผลิตของเราอย่างระมัดระวัง
Chris Knight

คุณสามารถอธิบายความหมายโดยดูอย่างระมัดระวังได้หรือไม่? อย่างไรและใคร? ความถี่ใด
โอ้ชินบุญ

ฉันควรจะพูดเมื่อต้องระวังโดยระมัดระวัง มันเป็นไฟล์บันทึกการหมุนซึ่งเป็นหนึ่งในหลาย ๆ พอร์ตการโทรหากมีสิ่งผิดปกติเกิดขึ้นกับแอพของเรา
Chris Knight

3

ในแอปพลิเคชันเซิร์ฟเวอร์ stacktrace จะระเบิดไฟล์ stdout / stderr ของคุณ อาจมีขนาดใหญ่ขึ้นเรื่อย ๆ และเต็มไปด้วยข้อมูลที่ไร้ประโยชน์เพราะโดยปกติแล้วคุณไม่มีบริบทและไม่มีการประทับเวลาเป็นต้น

เช่น catalina.out เมื่อใช้ tomcat เป็นคอนเทนเนอร์


จุดดี. การใช้ printStackTrace () ในทางที่ผิดอาจทำให้ไฟล์บันทึกของเราเสียหายหรืออย่างน้อยที่สุดก็กรอกข้อมูลที่ไร้ประโยชน์ลงไป
Chris Knight

@ChrisKnight - คุณช่วยแนะนำบทความที่อธิบายว่าการบันทึกไฟล์สามารถทำให้ข้อมูลที่ไร้ประโยชน์ได้อย่างไร? ขอบคุณ
MasterJoe

3

ไม่ใช่แนวทางปฏิบัติที่ไม่ดีเพราะมีบางอย่าง 'ผิด' เกี่ยวกับ PrintStackTrace () แต่เนื่องจากเป็น 'กลิ่นรหัส' ส่วนใหญ่จะมีการเรียก PrintStackTrace () เนื่องจากมีบางคนไม่สามารถจัดการกับข้อยกเว้นได้อย่างถูกต้อง เมื่อคุณจัดการกับข้อยกเว้นด้วยวิธีที่เหมาะสมโดยทั่วไปแล้วคุณจะไม่สนใจ StackTrace อีกต่อไป

นอกจากนี้การแสดง stacktrace บน stderr โดยทั่วไปจะมีประโยชน์เฉพาะเมื่อทำการดีบั๊กเท่านั้นไม่ใช่ในการผลิตเพราะบ่อยครั้งที่ stderr ไม่ไปไหน การบันทึกมันเข้าท่ากว่า แต่เพียงแค่แทนที่ PrintStackTrace () ด้วยการบันทึกข้อยกเว้นยังคงทำให้คุณมีแอปพลิเคชันที่ล้มเหลว แต่ยังคงทำงานต่อไปเหมือนไม่มีอะไรเกิดขึ้น


0

ดังที่บางคนได้กล่าวไว้แล้วที่นี่ปัญหาคือข้อยกเว้นการกลืนในกรณีที่คุณโทรเข้ามาe.printStackTrace()ในcatchบล็อก มันจะไม่หยุดการทำงานของเธรดและจะดำเนินการต่อหลังจากบล็อกการลองตามสภาพปกติ

แทนที่จะเป็นเช่นนั้นคุณต้องพยายามกู้คืนจากข้อยกเว้น (ในกรณีที่สามารถกู้คืนได้) หรือโยนRuntimeExceptionหรือทำฟองข้อยกเว้นให้กับผู้โทรเพื่อหลีกเลี่ยงการขัดข้องแบบไม่โต้ตอบ (ตัวอย่างเช่นเนื่องจากการกำหนดค่าคนตัดไม้ที่ไม่เหมาะสม)


0

เพื่อหลีกเลี่ยงปัญหาการสตรีมเอาต์พุตที่พันกันถูกอ้างถึงโดย @Vineet Reynolds

คุณสามารถพิมพ์ไปที่ stdout: e.printStackTrace(System.out);

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.