赞
踩
定义:异常就是有异于常态,和正常情况不一样,有错误出现。在java中,将程序执行过程中的不正常的情况称之为异常,开发过程中的语法错误和逻辑错误不是异常,发生异常时java会阻止当前方法或作用域的情况。
异常的体系结构
从程序执行的过程来看编译时异常和运行时异常
- package com.broky.exception.commonException;
-
- import java.util.Scanner;
-
- public class CommonEx {
- static void ArithmeticExceptionDemo(){
- int a = 10;
- int b = 0;
- int c = a / b;
- /*Exception in thread "main" java.lang.ArithmeticException: / by zero
- at com.broky.exception.ArithmeticEx.main(ArithmeticEx.java:7)*/
- }
-
- static void ClassCastExceptionDemo(){
- Object obj = new Double(1);
- String str = (String)obj;
- /*Exception in thread "main" java.lang.ClassCastException: class java.lang.Double cannot be cast to class java.lang.String (java.lang.Double and java.lang.String are in module java.base of loader 'bootstrap')
- at com.broky.exception.ClassCastEx.main(ClassCastEx.java:7)*/
- }
-
- static void InputMismatchExceptionDemo(){
- Scanner scan = new Scanner(System.in);
- int num = scan.nextInt();
- System.out.println(num);
- /*asd
- Exception in thread "main" java.util.InputMismatchException
- at java.base/java.util.Scanner.throwFor(Scanner.java:939)
- at java.base/java.util.Scanner.next(Scanner.java:1594)
- at java.base/java.util.Scanner.nextInt(Scanner.java:2258)
- at java.base/java.util.Scanner.nextInt(Scanner.java:2212)
- at com.broky.exception.InputMismatchEx.main(InputMismatchEx.java:8)*/
- }
-
- static void NullPointerExceptionDemo(){
- int[] arr = null;
- System.out.println(arr[3]);
-
- /*Exception in thread "main" java.lang.NullPointerException: Cannot load from int array because "arr" is null
- at com.broky.exception.NullPointerEx.main(NullPointerEx.java:6)*/
- }
-
- static void NumberFormatExceptionDemo(){
- String str = "abc";
- int a = Integer.parseInt(str);
- /*Exception in thread "main" java.lang.NumberFormatException: For input string: "abc"
- at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:67)
- at java.base/java.lang.Integer.parseInt(Integer.java:660)
- at java.base/java.lang.Integer.parseInt(Integer.java:778)
- at com.broky.exception.NumberMismatchEx.main(NumberMismatchEx.java:6)*/
- }
-
- static void ArrayIndexOutOfBoundExceptionDemo(){
- int[] arr = new int[3];
- System.out.println(arr[3]);
- /*Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3
- at com.broky.exception.XIndexOutOfBoundEx.main(XIndexOutOfBoundEx.java:6)*/
-
- String str = "abc";
- System.out.println(str.charAt(3));
- /*Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 3
- at java.base/java.lang.StringLatin1.charAt(StringLatin1.java:48)
- at java.base/java.lang.String.charAt(String.java:711)
- at com.broky.exception.XIndexOutOfBoundEx.main(XIndexOutOfBoundEx.java:11)*/
- }
-
- public static void main(String[] args) {
- ArrayIndexOutOfBoundExceptionDemo();
- }
- }
-
这个产生的异常对象会与catch的异常类型相匹配,匹配成功后就被 catch 捕获,然后运行catch{}中的代码, 一般catch中的代码为处理异常的代码, 比如返回异常的信息和返回异常的详细信息等. 一旦异常处理完成,就会跳出当前的try-catch结构
无论有没有发生异常finally中的代码都会最后被执行
- package com.broky.exception.demo02;
-
- public class TryCatchFinally {
- public static void main(String[] args) {
- String str = "abc";
-
- try {
- int i = Integer.parseInt(str);
- } catch (NumberFormatException e) {
- e.printStackTrace();
- } catch (Exception e) {
- System.out.println(e.getMessage());
- } finally {
- System.out.println("运行完毕");
- }
- }
- }
throws 一般用于方法中可能存在异常时, 需要将异常情况向方法之上的层级抛出, 由抛出方法的上一级来解决这个问题, 如果方法的上一级无法解决的会就会再将异常向上抛出, 最终会抛给main方法. 这样一来main方法中调用了这个方法的时候,就需要解决这个可能出现的异常.
当然main方法也可以不解决异常, 将异常往上抛出给java虚拟机, 如果java虚拟机也无法解决的话,那么java虚拟机就over了
throws + 异常类型
写在方法的声明处.指明此方法执行时,可能会抛出的异常类型.
一旦方法体执行时,出现异常,仍会在异常代码处生成一个异常类的对象,此对象满足throws后异常类型时,就会被抛出。
异常代码的后续的代码,就不再执行!
体会:tyr-catch-fianlly:真正的将异常给处理掉了。throws的方式只是将异常抛给了方法的调用者,并没有真正将异常处理掉。
注意: 将异常向上抛出也算是一种处理异常的方法
- package com.broky.exception;
-
- import java.io.FileNotFoundException;
-
- public class ThrowsEx {
- public void setAge2(int age) throws FileNotFoundException {
- if (age < 0) {
- throw new FileNotFoundException("输入的年龄小于0");
- }
- }
-
- public void TestsetAge2() throws FileNotFoundException {
- setAge2(2);
- }
-
- public static void main(String[] args) {
- try {
- ThrowsEx.throwsExTest();
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- }
- }
- }
下面代码中,main方法中向display方法中传入了SuperClass的子类对象.那么到display方法中调用s.method调用的就是SpuerClass的子类SubClass重写的method方法, 如果这个方法抛出的异常范围大于父类SuperClass所抛出的异常的话,那么在display方法中对异常的catch处理就会catch不到这个异常.
- package com.broky.exception;
-
- import java.io.FileNotFoundException;
- import java.io.IOException;
-
- public class OverrideTest {
- public void display(SuperClass s) {
- try {
- s.method();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- public static void main(String[] args) {
- OverrideTest overrideTest = new OverrideTest();
- overrideTest.display(new SubClass());
- }
- }
-
- class SuperClass {
- public void method() throws IOException {
- System.out.println("super");
- }
- }
-
- class SubClass extends SuperClass {
- public void method() throws FileNotFoundException {
- System.out.println("sub");
- }
- }
手动抛出的异常有两种, 分别为运行时异常和编译时异常.
抛出运行时异常时, 可以不用处理抛出的这个异常.
抛出编译时异常时, 必须要处理抛出的这个异常.
详细解析请看下面的代码
- package com.broky.exception;
-
- /*Demo
- 手动抛出异常
- 自己throw(制造一个异常抛出)
- */
-
-
- import java.io.FileNotFoundException;
-
- public class ThrowEx {
-
- // 手动抛出运行时异常
- public void setAge(int age) {
- if (age < 0) {
- throw new NullPointerException("输入的年龄小于0");
- }
- }
- /*
- 此方法手动抛出了运行时异常
- 运行时异常可以不用处理
- */
-
- // 手动抛出编译时异常
- public void setAge2(int age) throws FileNotFoundException {
- if (age < 0) {
- throw new FileNotFoundException("输入的年龄小于0");
- }
- }
- /*
- 此方法手动抛出的了编译时异常
- 编译时异常需要被处理
- 这里采用了 throws 这个异常, 也就是说方法并没有处理这个异常, 而是将异常抛给了调用者
- 这样一来调用了这个方法的人就必须要处理这个异常才可以.
- 注意: 在这里并不用自己使用 try catch 处理这个异常
- 自己在方法里抛出异常, 方法再自己处理没有任何作用.
- 所以方法中的异常需要抛给调用者去处理.
- */
-
-
- public static void main(String[] args) {
- ThrowEx throwEx = new ThrowEx();
-
- throwEx.setAge(-5);
- }
-
- }
-
- package com.broky.exception;
-
- public class MyException extends RuntimeException{
- static final long serialVersionUID = -1234719074324978L;
-
- public MyException(){
-
- }
-
- public MyException(String message){
- super(message);
- }
-
- public static void main(String[] args) {
- throw new MyException("自定义运行时异常");
- /*Exception in thread "main" com.broky.exception.MyException: 自定义运行时异常
- at com.broky.exception.MyException.main(MyException.java:15)*/
- }
- }
- package com.broky.exception.practice;
-
- public class ExceptionTest {
- static void methodA() {
- try {
- System.out.println("运行A方法");
- throw new RuntimeException("A方法手动抛出运行时异常");
- } finally {
- System.out.println("用A方法的finally");
- }
- }
-
- static void methodB() {
- try {
- System.out.println("进入B方法");
- return;
- } finally {
- System.out.println("用B方法的finally");
- }
- }
-
-
- public static void main(String[] args) {
-
- try {
- methodA();
- } catch (Exception e) {
- System.out.println(e.getMessage());
- }
-
- methodB();
- }
- }
- /*答案
- 运行A方法
- 用A方法的finally
- A方法手动抛出运行时异常
- 进入B方法
- 用B方法的finally
- */
解析debug中的运行步骤:
编写应用程序 EcmDef java,接收命令行的两个参数,要求不能输入负数,计算两数相除对数据类型不一致( Number FormatException)、
缺少命令行参数(ArraylndexOutofBounds Exception、除0( Arithmetic EXception)及输入负数( EcDef自定义的异常)进行异常处理。
提示:
java EcmDef 20 10
∥args[0]=“20“ args[1]=”10“ I- package com.broky.exception.practice;
-
- public class EcDef extends Exception{
- static final long serialVersionUID = -338751612344229948L;
-
- public EcDef(){
-
- }
-
- public EcDef(String str){
- super(str);
- }
-
- }
-
- package com.broky.exception.practice;
-
- public class EcmDef {
- public static int ecm(int a, int b) throws EcDef, ArithmeticException {
- if (a < 0 || b < 0)
- throw new EcDef("输入的数据小于0");
- if (b == 0)
- throw new ArithmeticException("除数不能等于0");
- return a / b;
- }
-
- public static void main(String[] args) {
- int a = 0;
- int b = 0;
-
- try {
- a = Integer.parseInt(args[0]);
- b = Integer.parseInt(args[1]);
-
- System.out.println(ecm(a, b));
- } catch (ArrayIndexOutOfBoundsException e) {
- System.out.println("缺少命令行参数");
- e.printStackTrace();
- } catch (NumberFormatException e) {
- e.printStackTrace();
- } catch (ArithmeticException e) {
- e.printStackTrace();
- } catch (EcDef ecDef) {
- ecDef.printStackTrace();
- }
-
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。