java 异常

目录

1、异常层次结构

2、三种异常

3、try-catch-finally

4、try-with-resources

5、使用

6、异常链

参考


异常很有用,能够将错误处理代码从“常规”代码中分离出来。

1、异常层次结构

所有异常都是java.lang.Exceptions的子类,而Exception又是Throwable的子类,Throwable还有一个子类为Errors。如图所示。

Exceptions1

2、三种异常

检查型异常:异常必须要被处理,比如使用try捕获异常或者在方法上抛出异常。通常是一些用户可以预测到和期待修改的异常。除了Error、RuntimeException及其子类,其他的都是检查型异常。

运行型异常:运行时异常可以不用被处理,如果发生运行时异常,通常表明对应的api使用不正确。运行时异常包括RuntiemException及它的子类。

错误:错误通常是由硬件或系统故障导致的,因此用户也不必捕获该异常,但是为了通知用户此类异常的方法,也可以选择捕获该异常。错误包含Error和它的子类。

3、try-catch-finally

下面是一个捕获异常的例子,在try语句中的语句用来检测异常,catch捕获异常,finally语句块中代码不管是否try发生异常都会执行。

public void writeList() {
    PrintWriter out = null;

    try {
        System.out.println("Entering" + " try statement");

        out = new PrintWriter(new FileWriter("OutFile.txt"));
        for (int i = 0; i < SIZE; i++) {
            out.println("Value at: " + i + " = " + list.get(i));
        }
    } catch (IndexOutOfBoundsException e) {
        System.err.println("Caught IndexOutOfBoundsException: "
                           +  e.getMessage());
                                 
    } catch (IOException e) {
        System.err.println("Caught IOException: " +  e.getMessage());
                                 
    } finally {
        if (out != null) {
            System.out.println("Closing PrintWriter");
            out.close();
        } 
        else {
            System.out.println("PrintWriter not open");
        }
    }
}

一个catch也可以同时捕获多个异常,通过|分隔,但是异常类型隐式final:

catch (IOException|SQLException ex) {
    logger.log(ex);
    throw ex;
}
  • 即使try中有return,finally也会别执行。在return语句执行之前,finally语句块会被执行。
  • catch和finally,两者可以省略一个。

4、try-with-resources

在try-with-resources的try块中声明的资源在try语句块结束后可以自动关闭,不用手动使用finally关闭了。

public class App 
{
	public static void main(String[] arg) {
	    try (BufferedReader br =new BufferedReader(new FileReader("D:\\A.java"))) {
	    	 br.readLine();
		 } catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

需要在try的括号中声明资源,资源对应的类需要实现java.lang.AutoCloseable接口。当try语句执行完或抛出异常时会立刻关闭资源,如果close方法抛出异常,则该异常会被抑制。然后才是捕获异常的步骤。

如果异常被抑制了,可以在catch语句中通过Throwabl的getSuppressed方法获得被抑制的异常,可以看看下面的例子:

public class TryWithResources {

	public static void main(String[] args) throws Exception {

		try ( OpenDoor door = new OpenDoor() ) {
			door.swing(); //this throws a SwingExecption
		}
		catch (Exception e) { 
			System.out.println("Is there a draft? " + e.getClass());
			int suppressedCount = e.getSuppressed().length;
			for (int i=0; i<suppressedCount; i++){
				System.out.println("Suppressed: " + e.getSuppressed()[i]);
			}
		}
		finally {
			System.out.println("I'm putting a sweater on, regardless. ");
		}
	}
}

class OpenException extends Exception {}
class SwingException extends Exception {}
class CloseException extends Exception {}

class OpenDoor implements AutoCloseable {

	public OpenDoor() throws Exception {
		System.out.println("The door is open.");
	}
	public void swing() throws Exception {
		System.out.println("The door is becoming unhinged.");
		throw new SwingException();
	}

	public void close() throws Exception {
		System.out.println("The door is closed.");
		throw new CloseException(); // throwing CloseException 
	}
}

5、使用

在编写自己的公有方法时,会时常抛出运行时异常,表明用户错误地使用API。比如传入的参数不正确,会抛出IllegalArgumentException异常。一些常用的运行时异常如下:

  1. IllegalArgumentException
  2. IllegalStateException
  3. NullPointerException
  4. IndexOutOfBoundsException
  5. ConcurrentModificationException
  6. UnsupportedOperationException

如果不满足使用,可以自定义异常。

对于非公有方法,这些方法一般是提供给自己使用的,因此可以不抛出异常,只需要添加注释约定方法的使用方式。

6、异常链

一个异常导致另一个异常,于是组成了异常链,最后抛出的异常链通常包裹着造成该异常的异常。只需要将内部异常传入外部异常构造函数即可。

例子:

class Untitled {
	public static void main(String[] args) throws AException{
		aMethod();
	}
	static public void aMethod() throws AException {
        try {
            throw new BException("B异常抛出");
        } catch (BException e) {
            throw new AException("A异常抛出;内部异常:"+e.getMessage(),e);
        }
    }
}
class AException extends Exception{
    public AException(String message) {
        super(message);
    }

    public AException(String message, Throwable cause) {
        super(message, cause);
    }
}
class BException extends  Exception{
    public BException(String message) {
        super(message);
    }

    public BException(String message, Throwable cause) {
        super(message, cause);
    }
}

输出:

Exception in thread "main" AException: A异常抛出;内部异常:B异常抛出
	at Untitled.aMethod(Untitled.java:9)
	at Untitled.main(Untitled.java:3)
Caused by: BException: B异常抛出
	at Untitled.aMethod(Untitled.java:7)
	... 1 more

参考

https://docs.oracle.com/javase/tutorial/essential/exceptions/index.html
https://www.theserverside.com/tutorial/OCPJP-OCAJP-Java-7-Suppressed-Exceptions-Try-With-Resources
Chained Exceptions in Java

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值