zoukankan      html  css  js  c++  java
  • 异常

    1、

    /*
     * 异常即是一种意外,是程序运行过程中产生的一种突发(意外)
     * 事件,该事件会干扰程序的正常执行,打破程序的正常流程。
     * 
     * 当异常产生时,会创建一个相关异常类的对象,该对象含有异常的
     * 相关信息。
     * 异常产生时,会在异常的上下文中寻找异常处理程序,如果没有
     * 异常处理程序,则异常产生之后的语句将不会得到执行。该异常
     * 会向上传播(传播给方法的调用端)。如果传播到main方法里,还
     * 未处理该异常,则main方法会将异常传播给JVM,此时,整个
     * 线程终止执行。在控制台会打印出异常的相关信息与堆栈的调用
     * 轨迹。该轨迹是按照方法调用的逆序打印,即离异常发生地最近
     * 的方法会最先打印。
     */
    package day12;
    
    public class ExceptionTest {
    	public static void main(String[] args) {
    		a();
    	}
    
    	public static void a() {
    		b();
    	}
    
    	public static void b() {
    		c();
    	}
    
    	public static void c() {
    		int x = 5;
    		int y = 0;
    		int z = x / y;
    		System.out.println("x除以y的结果是:");
    		System.out.println(z);
    	}
    }
    

      2、

    异常可以分成以下三种:

          受检异常      运行时异常           错误

    说明:运行时异常与错误统称为非受检异常。

    当异常发生时,我可以采用两种方式进行处理:

     捕获异常

     抛出异常

    说明:受检异常要求程序员在编译时显式处理,而非受检异常则不需要。

    3、异常处理

    /*
     * 异常处理程序(异常处理器)
     * try {
     * 		可能产生异常的程序
     * } catch (异常1) {
     * 		恢复措施
     * } catch (异常2) {
     * 		恢复措施
     * } ……
     * catch (异常n) {
     * 		恢复措施
     * }
     * 
     * try-catch的三种情况:
     * 1 try语句块中没有产生异常。此时try语句块全部执行完毕,
     * 之后执行try-catch之后的语句。
     * 2 try语句块中产生异常,catch捕获了该异常。
     * try中如果产生异常,则此时会创建一个相关异常类的对象,异常之后
     * 的语句将不会得到执行。程序会跳转到catch分支,从上到下依次使用
     * 异常类对象与每个catch中的异常类型进行匹配,哪一个catch分支
     * 匹配成功,则执行哪个catch语句块,此时异常被成功捕获。try-catch
     * 之后的语句正常执行。(最多只会执行一个catch分支)
     * 3 try语句块中产生异常,catch没有捕获该异常。
     * 当try中产生异常时,try异常之后的语句不会得到执行。程序
     * 跳转到catch分支进行异常匹配,没有匹配成功,则表示没有捕获
     * 该异常(该异常继续存在),则try-catch之后的语句不会得到
     * 执行,该异常会继续向上传播(传播给方法的调用端)。
     */
    package day12;
    
    public class Try {
    
    	public static void main(String[] args) {
    		try {
    			int x = 1;
    			// int y = 10;
    			int y = 0;
    			int z = x / y;
    			// System.out.println(z);
    			// String s = null;
    			// s.length();
    			// System.out.println("dd");
    		} catch (ArithmeticException e) {
    			// 打印异常错误的堆栈轨迹
    			e.printStackTrace();
    			// 打印异常的信息。
    			// System.out.println(e.getMessage());
    		}
    		System.out.println("try-catch后的语句执行");
    	}
    
    }
    

      4、finally

    /*
     * try-catch-finally
     * try-catch语句块可以同时使用finally。
     * catch与finally都是可选的。但是二者不能同时缺失。
     * finally的特征:
     * 不管try是否产生异常,也不管catch是否捕获了try中产生
     * 的异常,finally都将会得到执行。
     * 因为finally总是会得到执行(虚拟机退出的情况例外),所以
     * 我们在finally语句块中进行资源的释放是非常合适的。
     * 
     * finally中的返回值会镇压try中的返回值。
     */
    package day12;
    
    public class Finally {
    	public static void main(String[] args) {
    		try {
    			// System.out.println("没有产生异常");
    			// String s = null;
    			// s.length();
    			// System.out.println(5 / 0);
    			// 回收程序
    		} catch (NullPointerException e) {
    			// e.printStackTrace();
    		} finally {
    			// System.out.println("finally执行了");
    		}
    
    		// for (int i = 0; i < 10; i++) {
    		// try {
    		// break;
    		// } finally {
    		// System.out.println("finally执行了");
    		// }
    		// }
    		// f();
    		// try {
    		// // 退出虚拟机
    		// System.exit(0);
    		// } finally {
    		// System.out.println("finally执行了");
    		// }
    		System.out.println(g());
    	}
    
    	public static void f() {
    		try {
    			return;
    		} finally {
    			System.out.println("finally执行了");
    		}
    	}
    
    	// 返回的是fianlly中的return值。
    	public static int g() {
    		try {
    			return 1;
    		} finally {
    			return 2;
    		}
    	}
    }
    

      5、

    /*
     * 捕获异常时,如果多个catch捕获的异常类型存在父子关系,
     * 则需要将子类型方法前面,父类型放在后面。因为子类型能够
     * 捕获的,父类型都能够捕获,如果父类型的catch放在前面,
     * 则子类型的catch永远没有机会得到执行。
     */
    package day12;
    
    public class CatchOrder {
    
    	public static void main(String[] args) {
    		try {
    
    		} catch (NullPointerException e) {
    
    		} catch (RuntimeException e) {
    
    		} catch (Exception e) {
    
    		}
    		/*
    		 * try {
    		 * 
    		 * } catch(Exception e) {
    		 * 
    		 * } catch (RuntimeException e) { //永远没有机会得到执行 }
    		 */
    	}
    
    }
    

      6、多重捕获异常

    /*
     * 多重捕获异常
     * 
     * 当try语句块中,可能会产生多个异常,而多个异常的处理方式
     * 又完全相同时,我们就可以使用多重捕获异常。
     * 注意:不要使用多个异常的父类来代替多重捕获异常,因为父类
     * 会捕获更多的异常(我们意料之外的异常),这可能会隐藏掩盖
     * 我们程序的漏洞。
     * 
     * 当使用多重异常捕获时,catch捕获异常的参数将隐式使用final
     * 来修饰。
     */
    package day12;
    
    public class MultiCatch {
    
    	public static void main(String[] args) {
    		try {
    			// 可能产生异常的代码
    		} catch (ArithmeticException e) {
    			e.printStackTrace();
    		} catch (NullPointerException e) {
    			e.printStackTrace();
    		}
    		// 多重捕获
    		try {
    			// String s = null;
    			// s.length();
    			// System.out.println(1 / 0);
    		} catch (ArithmeticException | NullPointerException e) {
    			e.printStackTrace();
    			// e = null;
    		}
    
    		try {
    			String s = null;
    			s.length();
    			// System.out.println(1 / 0);
    		} catch (RuntimeException e) {
    			e.printStackTrace();
    		}
    	}
    
    }
    

      7、throws 异常列表

    /*
     * throws 异常列表
     * 
     * 如果一个方法中可能会抛出受检异常,则要求该异常必须
     * 同时声明在方法的异常列表中。对于非受检异常(运行时
     * 异常与错误),则不要求声明在方法的异常列表中。
     * 
     * 异常分为三种:
     * 1 受检异常(编译时异常)
     * 2 运行时异常
     * 3 错误
     * 运行时异常和错误统称为非受检异常。
     * 
     * 受检异常继承Exception类或其子类。
     * (不包括RuntimeException或其子类)
     * 运行时异常继承RuntimeException或其子类。
     * 错误继承Error类或其子类。
     * 
     * 受检异常与非受检异常的区别:
     * 受检异常必须在编译期间就需要明确对其进行处理,
     * 而非受检异常则不需要。
     */
    package day12;
    
    import java.io.FileNotFoundException;
    
    public class Throws {
    
    	public static void main(String[] args) {
    
    	}
    
    	public void f(int x, int y) throws FileNotFoundException {
    		if (x < 0) {
    			throw new NullPointerException();
    		}
    
    		if (y < 0) {
    			throw new FileNotFoundException();
    		}
    	}
    
    	// 该方法不会抛出FileNotFoundException(受检异常)
    	public void g(int x) {
    		// try {
    		// if (x < 0) {
    		// throw new FileNotFoundException();
    		// }
    		// } catch(FileNotFoundException e) { }
    	}
    
    }
    

      8、方法重写的第五条

    /*
     * 方法重写的第五条要求:
     * 子类重写父类的方法,则子类方法不能比父类方法抛出更多
     * 的受检异常。(只能与父类相同,或者是父类抛出受检异常的
     * 子类异常)。对于非受检异常,则不受限制。
     */
    package day12;
    
    public class Override5 {
    	public static void main(String[] args) {
    		Override5 o = new Override5();
    		o.use(new WhiteHorse());
    	}
    
    	public void use(Horse h) {
    		h.run();
    	}
    
    	/*
    	 * public int x() { throw new NullPointerException(); }
    	 */
    }
    
    class Horse {
    	public void run() {
    
    	}
    }
    
    class WhiteHorse extends Horse {
    	// 错误,子类方法比父类方法抛出了更多的受检异常。
    	/*
    	 * @Override public void run() throws Exception {
    	 * 
    	 * }
    	 */
    
    	@Override
    	public void run() throws NullPointerException, IllegalArgumentException {
    
    	}
    }
    

      9、手动抛出异常

    /*
     * 手动抛出异常 throw
     */
    package day12;
    
    public class Throw {
    	public static void main(String[] args) {
    		Throw t = new Throw();
    		t.deal(-1);
    		
    	}
    
    	public void deal(int age) {
    		if (age <= 0) {
    			throw new IllegalArgumentException("年龄必须大于0!输入年龄为:" + age);
    		}
    		System.out.println("执行了吗?");
    		// 对年龄进行处理
    	}
    }
    

      10、自定义异常

    /*
     * 自定义异常
     * 为什么要使用自定义异常?
     * 1 Java类库提供的异常类不能满足所有人的需要。
     * 2 自定义异常可以令我们快速定位问题。
     * 
     * 按照惯例,自定义异常名使用Exception进行结尾。
     */
    package day12;
    
    public class SelfException {
    	public void use() {
    		SelfException s = new SelfException();
    		//s.deal(-1);
    		try {
    			s.deal(-1);
    		} catch (NegtiveAgeException e) {
    			System.out.println("进行异常的处理");
    		}
    	}
    
    	public void deal(int age) {
    		if (age <= 0) {
    			throw new NegtiveAgeException("年龄为负!" + age);
    		}
    		System.out.println("年龄合理,进行处理。");
    	}
    }
    
    class NegtiveAgeException extends RuntimeException {
    	public NegtiveAgeException(String s) {
    		super(s);
    	}
    
    	public NegtiveAgeException() {
    		this("年龄为负数,请输入核对!");
    	}
    }
    

      11、异常优势:

    使用异常具有如下优势:
     可以将正常的代码与异常处理的代码相分离。
     可以将异常信息沿着方法调用轨迹向上传播。
     异常具有明确的类型与继承体系, 便于分类处理。
    

      补充:

    1、捕获异常

    使用try(尝试着)去执行可能产生异常的程序,一旦异常发
    生,系统会自动创建一个相应的异常类对象,同时终止try
    执行( try语句块异常产生位置之后的代码将不会执行)。
    一旦产生异常,将会从上到下去匹配catch中异常类,一旦匹
    配成功,则异常对象就会传递给catch参数,执行相应catch
    语句块。如果没有匹配成功,则该异常会继续向上抛出给方
    法调用端。
    catch语句块最多只会执行一个。如果所有方法中都没有合适
    的异常处理器,则当前线程终止。

    无论try是否抛出异常,也无论catch是否捕获异常, finally
    语句块都将在trycatch执行后执行。
    catch捕获的异常类型必须是Throwable类型或其子类型。
    finally是可选的。 catch也是可选的,但catchfinally不能
    同时为空。

    2、

    常见异常:
    1:非受检异常
    NullPointerException,ClassCastException,ArrayIndexsOutOfBoundsException,ArithmeticException(算术异常,除0溢出)
    2)受检:Exception,FileNotFoundException,IOException,SQLException.

  • 相关阅读:
    JAVA 正则表达式 (超详细)
    <select>改造成<s:select>实现表单的回显功能
    打开新界面
    list删除操作 java.util.ConcurrentModificationException
    C# 增加 删除 更新 方法
    C# 网页内容获取
    excel 处理方法
    C# 读取excel
    sql 导入excel 遇到问题
    DataSet
  • 原文地址:https://www.cnblogs.com/liuwei6/p/6572729.html
Copyright © 2011-2022 走看看