Java教程

笔记_from_Java编程思想(第十二章 通过异常处理错误)

本文主要是介绍笔记_from_Java编程思想(第十二章 通过异常处理错误),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

异常与记录日志

import java.util.logging.Logger;
import java.io.*;
class LoggingException extends Exception
{
    //静态的Logger.getLogger()方法创建了一个String参数相关联的Logger对象(通常与错误相关的包名或类名)
    //该Logger对象会将其输出发送到System.err
    private static Logger logger= Logger.getLogger("LoggingException");
    public LoggingException()
    {
        StringWriter trace= new StringWriter();
        /*为产生日志记录消息,我们需要获取异常抛出处的栈轨迹,但printStackTrace()不会默认产生字符串
        因此,使用重载的printStackTrace(),它接受java.io.PrintWriter对象作为参数,此对象(即trace)传入
        后,调用toString()就可以将输出抽取为String。*/
        printStackTrace(new PrintWriter(trace));
        //向Logger写入的最简单方式就是直接调用与日志记录消息级别相关联的方法,这里为serve()
        logger.severe(trace.toString());
    }
}
public class test
{
    public static void main(String[] args) {
        try
        {
            throw new LoggingException();
        }
        catch(LoggingException e)
        {
            System.err.println("Caught"+e);
        }
        try
        {
            throw new LoggingException();
        }
        catch(LoggingException e)
        {
            System.err.println("Caught"+e);
        }
    }
}
/*
输出:
7月 06, 2021 10:50:24 上午 LoggingException <init>
严重: LoggingException
        at test.main(test.java:18)

CaughtLoggingException
7月 06, 2021 10:50:24 上午 LoggingException <init>
严重: LoggingException
        at test.main(test.java:26)

CaughtLoggingException
*/

更常见的情形是,我们需要捕获和记录其他人编写的异常:

import java.util.logging.Logger;
import java.io.*;
class LoggingException
{
    private static Logger logger= Logger.getLogger("LoggingException");
    public LoggingException(Exception e)
    {
        StringWriter trace= new StringWriter();
        e.printStackTrace(new PrintWriter(trace));
        logger.severe(trace.toString());
    }
}
public class test
{
    public static void main(String[] args) {
        try
        {
            throw new NullPointerException();
        }
        catch(NullPointerException e)
        {
           new LoggingException(e);
        }
    }
}
/*
输出:
7月 06, 2021 11:11:32 上午 LoggingException <init>
严重: java.lang.NullPointerException
        at test.main(test.java:18)
 */

栈轨迹

printStackTrace()方法所提供的信息可以通过getStackTrace()方法直接访问,这个方法将返回一个由栈轨迹中的元素所构成的数组,其中每一个元素都表示栈中的一帧。元素0是栈顶元素,并且是调用序列中的第一个方法调用。

RuntimeException

import javax.management.RuntimeErrorException;

public class test
{
    static void f()
    {
        throw new RuntimeException();
    }
    static void g()
    {
        f();
    }
    public static void main(String[] args) {
        g();
    }
}
/*
输出:
Exception in thread "main" java.lang.RuntimeException
        at test.f(test.java:7)
        at test.g(test.java:11)
        at test.main(test.java:14)
*/

RuntimeException和它的子类,在编译器里没有被说明。如果RintimeException没有被捕获而直达main(),那么程序退出前将调用异常的printStackTrace()方法。注意:只能在代码中忽略RuntimeException和它的子类类型的异常,其他类型异常处理都是由1编译器强制实施,究其原因,RuntimeException代表的是编程错误。

使用finally进行清理

class isException extends Exception{}
public class test
{
    static int count=0;
    public static void main(String[] args) {
        while(true)
        {
            try
            {
                if(count++==0)
                    throw new isException();
                System.out.println("No exception");
            }
            catch(isException e)
            {
                System.out.println("isException");
            }
            finally
            {
                System.out.println("In finally clause");
                if(count==2)
                {
                    System.out.println("count==2");
                    break;
                }
            }
        }
    }
}
/*
输出:
isException
In finally clause
No exception
In finally clause
count==2
*/

从输出结果中看出,无论异常是否被抛出,finally子句总能被执行。
作用:对于没有垃圾回收和析构函数自动调用机制的语言来说,finally非常重要。它能使程序员保证:无论try块里发生什么,内存总得到释放。但Java有垃圾回收机制,所以内存释放不再是问题。而且Java也没有析构函数可调用。但在以下方面就用得上finally了:
当要把除内存之外的资源恢复到它们初始状态时,就要用到finally子句。这种需要清理的资源包括:已经打开的文件或网络连接,在屏幕上画的图形,甚至可以是外部世界的某个开关

在return中使用finally

public class test
{
    public static void f(int i)
    {
        System.out.println("Initialization that requires cleanup");
        try
        {
            System.out.println("Point 1");
            if(i==1)    return;
            System.out.println("Point 2");
            if(i==2)    return;
            System.out.println("Point 3");
            if(i==3)    return;
            System.out.println("end");
            return;
        }
        finally
        {
            System.out.println("Performing cleanup");
        }
    }
    public static void main(String[] args) {
        for(int i=1;i<=4;f(i),i++);
    }
}
/*
输出:
Initialization that requires cleanup
Point 1
Performing cleanup
Initialization that requires cleanup
Point 1
Point 2
Performing cleanup
Initialization that requires cleanup
Point 1
Point 2
Point 3
Performing cleanup
Initialization that requires cleanup
Point 1
Point 2
Point 3
end
Performing cleanup
*/

因为finally子句总是会执行,所以在一个方法中可以从多个点返回,而且可以保证重要的清理工作仍旧会执行。

这篇关于笔记_from_Java编程思想(第十二章 通过异常处理错误)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!