异常

异常概念

    1.异常是指程序在运行过程中遇到了一些无法处理的情况,这时JVM会向控制台打印错误信息,并停止程序。

  这不是我们想看到的结果,基于此,Java为我们提供了一种异常处理机制可以使我们程序发生异常情况时,可以跳过代码的异常,继续向下执行。

    2.JVM处理异常的默认方式;

        1).JVM执行到有异常的代码;2).JVM会识别出这种异常;3).JVM会到类库中找到描述这种异常的异常类——JVM为每种异常情况都定义了异常类。并创建了异常对象;4).JVM会到代码中查看我们的代码是否捕获这种异常:

                      是:JVM会执行异常处理代码-catch     否:JVM会向控制台打印异常信息,并结束程序。

异常和错误的区别:

  Throwable(所有异常跟错误的根类)

             1 Error(错误):我们不需要捕获,因为捕获也没有意义

             2 Exception(异常):我们程序需要捕获并处理的

                        1)RuntimeException(运行时异常)

                        2)其它的异常(编译期异常)

常见的运行时异常:

1.空指针异常---NullPointerException:

例子:

int[] arr1 = null;
System.out.println(arr1.length);
//NullPointerExcepiton--空指针异常

2.数据索引越界异常---ArrayIndexOutOfBoundsException

例子:

int[] arr2 = {1,2,3};
System.out.println(arr2[30]);
//ArrayIndexOutOfBoundsException--数组索引越界异常

3.字符串索引越界异常---StringIndexOutOfBoundsException

例子:

String str = "Hello";
System.out.println(str.charAt(30));
//StringIndexOutOfBoundsException--字符串索引越界

4.数学运算异常---ArithmaticException

例子:

int a = 10 / 0;
System.out.println("a = " + a);
//ArithmeticException--数学运算异常

 

异常处理throw抛出

例子:

public class Demo {
    public static void main(String[] args) {
        int[] arr = null;
        if(arr == null){
            //抛出异常--抛给此方法的调用者--JVM
            throw new NullPointerException("空指针异常!");
        }
        System.out.println(arr.length);
    }
}

异常处理Objects requireNonNull方法

例子:

	class Student{
			private String name;
			private String address;
			public Student(String name,String address){
				/*
				if(name == null){
					//抛出异常--相当于return,立即结束方法,向调用者返回一个异常对象
					throw new NullPointerException("名字不能为null");
				}
				if(address == null){
					throw new NullPointerException("地址不能为null");
				}
				*/
				//Objects的requeireNonNull()方法内部会判断参数是否为null,是:抛出异常
				//这样就不需要我们自己判断,它会为我们判断。
				this.name = Objects.requireNonNull(name);
				this.address = Objects.requireNonNull(address);
			}
		}
		main(){
			Student stu = new Student(null,"北京");
		}

异常处理throws声明抛出

例子:

public static void main(String[] args) {
    int[] arr = {432,43,24,32,432,43,24,3243};
    int r = sum(null);
    System.out.println("累加和是" + r);


}

//throws的作用:告诉JVM,我这个方法中可能会抛出这个异常,如果真的发生这个异常
//请将这个异常对象抛给"调用处"。
public static int sum(int[] arr) throws NullPointerException,
                                        ArrayIndexOutOfBoundsException{
    int sum = 0;
    for (int i = 0; i < arr.length; i++) {
        sum += arr[i];

    }
    return sum;
}

注意:1.如果throws抛出的是“运行时异常”,调用处可以不处理,编译会通过,但如果真的出现异常,仍然会终止程序

           2.如果throws跑出的是“编译期异常”,调用处必须处理(try...catch抛出),否则编译错误。

异常处理try...catch语句

    格式:

         try{

         //可能出现异常的代码     

}catch(异常类型名  变量名){

           //如果try中出现了与“异常类型名”一样的异常,就会执行这个catch语句

}

例子:

public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    while(true) {
        System.out.println("请输入年龄:");
        try {
            int age = sc.nextInt();
            System.out.println("你的年龄是:" + age);
            break;
        } catch (InputMismatchException e) {
            sc = new Scanner(System.in);
            System.out.println("哥们,请输入数字!");
        }
    }
    System.out.println("后续程序...");
}

异常处理 异常对象的操作

变量名.getMessage();          异常信息

变量名.toString();           异常类名+异常信息

变量名.printStacktrace();  常用在测试的时候,上线后写日志

例子:

public class Tets {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3};
        try {
            System.out.println(arr[10]);
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("异常信息:"+e.getMessage());
            System.out.println("toString:"+e.toString());
            e.printStackTrace();
        }
    }
}
结果为:
异常信息:10
toString:java.lang.ArrayIndexOutOfBoundsException: 10
java.lang.ArrayIndexOutOfBoundsException: 10
	at cn.itcast.demo01.Tets.main(Tets.java:7)

异常处理  多catch语句

基本格式:try{

//...

//...

//...

}catch(异常类名1  变量名){

}catch(异常类名2  变量名){

}...

代码:

public class Test {
    public static void main(String[] args) {
        try {
            int[] arr = null;
            System.out.println(arr.length);
            int[] arr2 = {1, 2, 3};
            System.out.println(arr2[4]);
            int a = 10 / 0;
            System.out.println(a);
        } catch (NullPointerException e) {
            System.out.println("空指针异常");
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("数据索引越界异常");
        } catch (ArithmeticException e) {
            System.out.println("数学运算异常");
        } catch (Exception e) {
            System.out.println("其它的异常,由我来处理");
            System.out.println("我只能写在多个catch的最后");
        }
    }
}
运行结果:空指针异常
注意:这种写法假如第一个catch语句执行后后面的就不会执行了。

假如第一个出异常,还想执行后面的,就必须分开来写。

例如:

public class Test1 {
    public static void main(String[] args) {
        try {
            int[] arr = null;
            System.out.println(arr.length);
        } catch (NullPointerException e) {
            System.out.println("空指针异常");
        }
        try {
            int[] arr2 = {1, 2, 3};
            System.out.println(arr2[4]);
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("数据索引越界异常");
        }
    }
}

空指针异常
数据索引越界异常

异常处理  try_catch_finally

格式:try{

...

}catch(异常类型名    变量名){

...

}finally{

...//无论是否出现异常都会被执行的代码 ,尤其在方法中,当try中有return时,需要关闭资源时尤其有用。

}

例如:

public class Test2 {
    public static void main(String[] args) {
        try {
            System.out.println("打开文件...");
            System.out.println("读取文件...");
            int a = 10 / 0;
            return "文件内容";//在执行return的过程中,会去调用finally
        } catch (Exception e) {
            System.out.println("出现异常");
            return null;
        } finally{
            System.out.println("关闭文件");
        }
    }
}

自定义异常

在我们的程序中,根据某些业务,需要抛出某种异常,但类库中没有,这时我们就可以自定义异常。

例如:

public class Student{
      private int age;
      public void setAge(int age){
      if(age<15||age>50){
      //必须要想办法通知调用出,这个参数不正确 
      //抛出异常
      throw new 自定义异常对象();
    } 
      this.age=age;
  }
}

自定义异常继承RuntimeException(运行时异常)演示:

自定义异常

public class AgeException extends RuntimeException{
    public AgeException(){
  } 
    public AgeException(String message){
       super(message); 
  }
}

使用自定义异常

public class Student{
 private int age;
 public void setAge(int age){
  if(age<15||age>50){
     throw new AgeException("年龄必须在15到50之间")
   }
    this.age=age;
  }
}

测试类

public class Demo{
  public static void main(String[] args)
     Student stu=new Student();
     try{
          stu.setAge(10);
     }catch(AgeException e){
      System.out.println("异常信息:"+e.getMessage());
  }
}
这个结果就为自己定义所抛出的那句话

自定义类继承自Exception(编译期异常)演示

自定义异常

public class NameException extends Exception{
    public NameException() {
    }

    public NameException(String message) {
        super(message);
    }
}

使用自定义异常

public class Person  {
    private String name;


    public Person(String name) throws NameException {
        if (name == null) {
            throw new NameException("请输入名字");
        }
        this.name = name;
    }
}

测试类

public class Test {
    public static void main(String[] args) {
        try {
            Person p = new Person(null);
        } catch (NameException e) {
            System.out.println(e.getMessage());
        }
    }
}
结果就为使用自定义异常时要抛出的那句话

异常_子类重写父类方法时的异常抛出

calss Fu{
   public void show(){}            //不抛出任何异常
   public void show2()throws NullPointerException{}    //抛出运行时异常    
   public void show3()throws IOException{}        //编译期异常
}
class Zi extends Fu{
   //子类重写这三个方法
    1)不抛任何异常
    2)可以抛出任何的运行时异常
    3)不能抛出比父类更多的编译期异常
}

异常注意事项:

运行时异常被抛出可以不处理,既不捕获也不声明抛出

如果父类抛出了多个异常,子类覆盖父类方法时,只能抛出相同的异常或者是它的子集

父类方法没有抛出异常,子类覆盖父类该方法时也不可抛出异常,子类产生异常,只能捕获处理,不能声明抛出

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值