Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 353|回复: 0

[Java基础知识]捕捉未捕获的异常

[复制链接]
  • TA的每日心情
    开心
    2021-3-12 23:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-10-1 23:08:26 | 显示全部楼层 |阅读模式
    在该技巧中,你将学习另外一个处理异常的方法。我们是通过J2SE 5.0 新增的UncaughtExceptionHandler接口来处理。        UncaughtExceptionHandler名字意味着处理未捕获的异常。更明确的说,它处理未捕获的运行时异常。java编译器要求处理所有非运行时异常,否则程序不能编译通过。这里“处理”的是方法里throws子句声明的异常或在try-catch块里的catch子句的异常。
             在下面的示例中,让我们关注两个异常:
    FileNotFoundException和ArithmeticException。

         如果使用一个不正确的String或File参数值来构造FileReader时,将会抛出FileNotFoundException异常。当你调用这些构造函数时,编译器要求你处理每一个可能抛出异常的子句:   
      
       
       
       

       
      

      FileReader input;
           String filename = ...;
           try {
             input = new FileReader(filename);
           } catch (FileNotFoundException e) {
             proceSSMissingFile(filename, e);
           }
                我们再来比较一下,ArithmeticException是一个运行时异常。Java编程语言规范(对于编译器而言)不要求处理运行时异常。因此在下面的循环中,从10到0都会被100除,而在最后一次循环中将抛出ArithmeticException异常:
      
       
       for (int i=10; i >= 0; i--) {
             int div = 100 / i;
           }
       
      
       
          Exception in thread "main" java.lang.ArithmeticException: /
           by zero
                at Test.main(Test.java:4)
                输出堆栈信息显示出缺省未捕获的异常内容。通常说来,这样的缺省行为已经足够了,不过有时也不行。设想你想在弹出式窗口输出堆栈信息,来替代在系统控制台输出该信息。如果你自己设置一个缺省的未捕获异常处理,你就可以得到这样的效果。
             这里有三个最新的处理未捕获异常的方法。
    第一,你可以调用Thread的setUncaughtExceptionHandler()方法。这个方法允许你在特殊的线程里定制行为。

    第二,你可以定义你自己的ThreadGroup并改变行为使每个线程都从这个组中创建并重写它们的uncaughtException()方法。

    第三,你可以设置缺省行为让所有线程调用Thread的静态方法setDefaultUncaughtExceptionHandler()。
             Thread的setUncaughtExceptionHandler()和setDefaultUncaughtExceptionHandler()方法都需要实现UncaughtExceptionHandler接口作为参数。该接口是Thread类的内部接口,因此它的全名是Thread.UncaughtExceptionHandler。该接口的唯一方法是:
      
       
       void uncaughtException(Thread t, Throwable e)
       
      
       
       当你实现了uncaughtException方法或实现了该接口或重写ThreadGroup的方法,你都可以定制其行为。在下面的示例中,我们实现了UncaughtExceptionHandler,无论运行时异常何时发生,堆栈信息都会显示在窗口的文本区域里。你可以在两个异常间关闭窗口。当下次异常发生时,窗口会再次出现在其他窗口之前。
      
       
       
         import java.awt.*;
           import java.io.*;
           import javax.swing.*;
       
      
       
          public class StackWindow extends JFrame
               implements Thread.UncaughtExceptionHandler {
       
      
       
            private JTextArea textArea;
       
      
       
            public StackWindow(
        String title, final int width, final int height) {
               super(title);
               setSize(width, height);
               textArea = new JTextArea();
               JScrollPane pane = new JScrollPane(textArea);
               textArea.setEditable(false);
               getContentPane().add(pane);
             }
       
      
       
            public void uncaughtException(Thread t, Throwable e) {
               addStackInfo(e);
             }
       
      
       
            public void addStackInfo(final Throwable t) {
               EventQueue.invokeLater(new Runnable() {
                 public void run() {
                   // Bring window to foreground
                   setVisible(true);
                   toFront();
                   // Convert stack dump to string
                   StringWriter sw = new StringWriter();
                   PrintWriter out = new PrintWriter(sw);
                   t.printStackTrace(out);
                   // Add string to end of text area
                   textArea.append(sw.toString());
                }
             });
           }
          }
       
      
       
       要测试这个处理,你需要一个程序来设置这个处理并抛出一些运行时异常。在下面的程序中,DumpTeat将会这样做。为了简单,DumpTest仅仅产生两个异常。如果要抛出更多的异常,你可以自由的在程序里添加更多的错误代码。程序在第一个异常显示后会暂停,你可以在异常间关闭异常堆栈窗口。
      
       
       import java.io.*;
       
      
       
          public class DumpTest {
            public static void main(final String args[])
             throws Exception {
               Thread.UncaughtExceptionHandler handler =
                 new StackWindow("Show Exception Stack", 400, 200);
               Thread.setDefaultUncaughtExceptionHandler(handler);
               new Thread() {
                 public void run() {
                   System.out.println(1 / 0);
                 }
               }.start();
               BufferedReader br =
                 new BufferedReader(new InputStreamReader(System.in));
               System.out.print("Press Enter for next exception");
               br.readLine();
               new Thread() {
                 public void run() {
                   System.out.println(args[0]);
       
        //这里有异常产生
                 }
               }.start();
               System.out.print("Press Enter to end");
               br.readLine();
               System.exit(0);
             }
           }
       
      
       
       编译StackWindow和DumpTest。当你运行DumpTest时,在控制台里会看见下面的内容: > java DumpTest
           Press Enter for next exception
        你将看见堆栈信息显示在窗口里的文本区域里。

      

      按下Enter,在控制台里回看见下面的内容: Press Enter to end
        你可以在窗口的文本区里看见另一个堆栈信息。

      

      虽然你可以认为这些是处理未捕获的异常的所有方法,其实还有更多的方法。模式对话框要求有它自己的事件线程,因为它自己非捕获处理。系统属性sun.awt.exception.handler覆盖了所有容器,但不是好的文档。RFE(增强型请求)提交了可扩展的属性到正式的API中。 除Best Practices in Exception Handling外,2002年5月的技巧文章StackTraceElements也是一篇重要的参考。也可以看The Java Tutorial的Handling Errors Using Exception课程。
      

      
      
       
       

         
       

         
       
      
      

    源码下载:http://file.javaxxz.com/2014/10/1/230825281.zip
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-5-18 19:26 , Processed in 0.344786 second(s), 38 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表