Java 异常

1、异常简介

Java 异常是程序中的某些错误,是Java 提供的一种面对程序运行错误时 提供的 应对机制。

在程序运行时抛出异常可以使程序不中断的运行下去,开发或维护人员能够了解异常的起因、异常的发生处以及抛出了什么异常。

异常结构:

error :出现error 基本上是硬件出错,说明程序崩了

exception:出现异常基本上是 编码、环境、用户操作或者输入问题

runtimeException 运行时异常:Java虚拟机会自动抛出,绝大部分都说明了代码本身有问题

checkException  检查异常:需要手动添加捕获及处理语句

-----

运行时异常和检查异常的区别:

运行时异常又叫非检查异常,一般情况下不需要程序员主动的捕获,但是一旦抛出了异常,就会一层层往上抛,如果最上层也没有相应的处理代码,此时程序就会中断。也因此,若想进程一直持续运行,那么对于所有可能会抛出异常的代码块,都要给他加上try catch 捕获并作出相应的异常处理机制。

检查异常是Java编译器强制要求必须要显示捕获的异常。

2、try catch finally 语句块

try:可能抛出异常的语句

catch: 异常处理的信息,可以打印异常日志、输出系统提示啥的;有可能一段代码会抛出多个异常,这时可以用多个catch块来捕获异常,catch块要遵循先子类后父类异常的原则

finally: 最终执行的,可用来关闭资源等

3、关于在finally前return

finally 是在try catch 语句块中的return  “执行完之后,返回调用前”  执行的;

如果try catch finally 中都没有return ,那会调用在最后面的return

       public static void main(String[] args){
		//finally在前面的return “执行完之后,返回调用前执行”, 一定会执行!
		int test1 = testTryCatch();
		System.out.println(test1);
		/**
		 * 不捕获异常:
		 * 我是finally语句块,最终执行的是我
			1

		 * 捕获异常:
		 * java.lang.ArrayIndexOutOfBoundsException: 2
				at test.TestException.testTryCatch(TestException.java:65)
				at test.TestException.main(TestException.java:8)
			我是catch块,我捕获异常了
			我是finally语句块,最终执行的是我
			0
		 */
	}

        public static int testTryCatch(){
		int[] nums = new int[2];
		nums[0] = 1;
		try{
			//System.out.println(nums[2]);
			return nums[0];
		}catch(Exception e){
			e.printStackTrace();
			System.out.println("我是catch块,我捕获异常了");
			
			//在catch块中return,后面还有finally的情况下,先把return的值执行了或者说先行保留,
			//等finally执行完在返回给这个方法的调用
			return nums[0] = 0;
		}finally {
			System.out.println("我是finally语句块,最终执行的是我");
		}
	}

  

4、异常抛出

throws:声明将要抛出何种类型的异常,在类或方法中声明,返回给上层调用者处理异常;throws  exception1,exception2

throw:将产生异常的动作抛出,表示这个动作,相当于try catch; throw new exception("产生异常了");

       public static void main(String[] args){
		//这里属于起始调用者,就直接自己处理异常即可,
		//如果不是起始调用者或者处理不了异常代码,就继续throw异常,并在方法名上声明要抛出
		try {
			testThrowException();
		} catch (Exception e) {
			e.printStackTrace();
		}
		/**
		 * java.lang.Exception
				at test.TestException.testThrowException(TestException.java:78)
				at test.TestException.main(TestException.java:12)
		 */
	}

        //在方法内部会抛出异常的时候,在方法头要声明这个方法会抛出异常,有多个异常的话就用逗号隔开
	//在调用这个方法的时候,要么自己try catch处理这个异常,要么在调用这个方法的方法声明处声明会抛出异常,丢给起始调用者处理异常
	public static void testThrowException() throws Exception{
		if(true){
			throw new Exception();
		}
		
	}

  

 注意抛出和捕获的区别:

抛出就是我发现这个异常,谁调用我,就把这个异常丢给谁来处理

捕获就是,我发现这个异常,我自己来处理

通常情况下,如果要调用可能会抛出异常的方法或代码块,就用try catch来被捕获处理这段调用代码,此时,一旦调用方法抛出异常,就会被trycatch捕获并且处理,这样主程序就不会中断了。

5、自定义异常

一般情况下,直接继承Exception的会是检查性异常
直接继承RuntimeException 的当然是运行时异常
如果只是在已有异常的基础上修改某些逻辑,则可以直接继承该异常

6、异常链

把捕获的异常包装成新的异常,在新的异常里面添加对原始异常的引用,在把新异常抛出,类似链式反应,一个导致另外一个,这种就叫异常链。

(所以一般在程序抛出异常时,最下面的那个cause by 往往是直接原因)

      public static void main(String[] args){
		//因为把自定义异常包装成了RuntimeException,所以这里就不需要自己显示捕获异常了
		testChainException();
	    /**
	     * 可见这里执行之后先抛出运行时异常,下面的Caused by 才是原本自定义的异常
	     * 也因为这个原因,在Java代码编写中,一般抛出异常,最下面的才是最主要的原因
	     * 
	     * Exception in thread "main" java.lang.RuntimeException: 把自定义异常包装成运行时异常!
				at test.TestException.testChainException(TestException.java:88)
				at test.TestException.main(TestException.java:33)
			Caused by: test.TestSelfException: 自定义异常:就是异常了!
				at test.TestException.testSelfException(TestException.java:77)
				at test.TestException.testChainException(TestException.java:86)
				... 1 more
	     */
		
	}

/**
	 * 自定义异常
	 * @throws TestSelfException 
	 */
	public static void testSelfException() throws TestSelfException{
		if(true){
			throw new TestSelfException("自定义异常:就是异常了!");
		}
	}
	
	/**
	 * 异常链
	 */
	public static void testChainException(){
		try {
			testSelfException();
		} catch (TestSelfException e) {
			RuntimeException rte = new RuntimeException("把自定义异常包装成运行时异常!");
			rte.initCause(e);
			throw rte;
		}
	}

  

7、应用总结

最好是在打印异常的同时加上业务回滚之类的,具体的看具体业务

-------------------------------------------------------------------------------------------------------------------------------------------------------------- 白云苍狗时光飞,嘻嘻哈哈一生追。哈!
原文地址:https://www.cnblogs.com/sangong/p/9440171.html