异常--------JavaSE

在java中,所有的异常类型都是java.lang.Throwable的子类,在Throwable下面有两个异常的分支,一个是Exception一个是error;

Error指的是java运行时的内部错误和资源耗尽错误,应用程序不会抛出此类异常,这种内部错误一旦出现,除了告知用户程序终止之外,其他的也无能为力,例如堆栈溢出是这种错误的一例

1)运行时异常(非受查异常)都是 RuntimeException 类及其子类异常,例如NullPointerException,IndexOutOfBoundsException,ArithmeticException他是点击运行程序之后抛出的异常,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般由程序逻辑错误引起,程序应该从逻辑角度尽可能避免这类异常的发生。

2)非运行时异常(受查异常),他是在程序进行编译的时候就会抛出的异常,我们必须在程序运行之前进行处理,例如 IOException、ClassNotFoundException,CloneNotSupportedException,但是IOException又可以分为EOFException,FileNotFoundException

1.用try catch来进行捕获异常

try代码块中放的是可能出现异常的代码,catch代码块中存放的是出现异常后的处理行为,finally是用于代码块的善后处理工作,一般是在最后面执行;

1,不进行处理异常,就发现程序会终止在出现异常的地方,后面不会再继续执行,因为程序会把异常直接交给JVM来进行处理,这样的处理结果是,程序会抛出异常,并且不会再继续向下执行
  int[] arr1={1,2,3};
   System.out.println(arr1[0]);
   System.out.println(arr1[3]);
   System.out.println("hello");
2,但是此时当程序进行用try catch来进行包裹异常的时候程序会自己在catch中处理异常,这样处理的结果是程序会自动向下执行,但是一旦try中发现异常的语句,就会立即跳到catch语句里面,try之后代码块的语句不会执行,catch执行完毕之后会继续向下自动执行
      int[] arr1={1,2,3};
  try{
      System.out.println(arr1[0]);
      System.out.println(arr1[4]);
      System.out.println("我爱我的家");
  }catch(ArrayIndexOutOfBoundsException e)//这里面的ArrayIndexOutOfBoundsException不可以换成其他的异常,否则还是会交给JVM进行处理
  {

  }
  System.out.println("我爱我的祖国");
最终我们打印的结果是1,我爱我的祖国

finally中的代码手机一定会被执行的,所以我们会优先执行finally中的return语句

catch也可以有多个,finally常常用于最后的善后工作,例如释放资源,无论是否发生异常,finally的代码块最终一定会被调用到

int[] arr1={1,2,3,4,5,6,7};
  try{
      arr1=null;
      System.out.println("hehe");
      System.out.println(arr1[5]);
      System.out.println("heihei");
  }catch(ArrayIndexOutOfBoundsException e)
  {
      e.printStackTrace();
      System.out.println("此时发生了数组越界异常·");
  }catch (NullPointerException e)
  {
      e.printStackTrace();
      System.out.println("此时发生了空指针异常");
  }
最终打印结果的值是hehe,此时发生了空指针异常
Scanner scanner=new Scanner(System.in);
  try{
      int num= scanner.nextInt();
      System.out.println(10/num);
  }catch(InputMismatchException e)
  {
      e.printStackTrace();
      System.out.println("输入错误");
  }catch (ArithmeticException e)
  {
      e.printStackTrace();
      System.out.println("算数异常,可能0作为了除数");
  }finally{
      scanner.close();
      System.out.println("finally代码块最终执行了");
  }
0
算数异常,可能0作为了除数
finally代码块最终执行了

示例代码:用try回收资源

try(Scanner scanner=new Scanner(System.in)){
    int num= scanner.nextInt();
    System.out.println(10/num);
}catch(InputMismatchException e)
{
    System.out.println("此时发生了输入错误");
}catch(ArithmeticException e)
{
    System.out.println("此事发生了算数异常,可能0作为了分母");
}
    }

如果此方法中没有合适的处理异常的方式,就会沿着调用栈向上进行传递

public static void func(int n)
    {
        System.out.println(10/n);
    }
    public static void main(String[] args) {
   try{
       func(0);
   }catch(ArithmeticException e)
   {
       System.out.println("此时发生了算数异常");
   }
    }
最终交给了main函数来进行处理

但是如果说一直向上传递都没有合适的方法去处理异常(main函数里面都没有try Catch)那么最终就会交给JVM来进行处理(和我们最开始没有使用try catch是一样的)

 public static void func(int n)
    {
        System.out.println(10/n);
    }
    public static void main(String[] args) {
        func(0);
        System.out.println(123);
    }
这个程序最终什么结果都不会进行打印
 public static int func()
    {
        int a=10;
        try{
            return a;
        }catch(ArithmeticException e)
        {
            e.printStackTrace();
        }finally{
            System.out.println("1");
            return 20;
        }
    }
    public static void main(String[] args) {
        int num=func();
        System.out.println(num);

    }
最终打印结果是1 20

下面我们来进行总结:

1)程序会先进行执行try中的代码

2)如果try中的代码出现了异常,就会结束try中的代码,看看是否与catch中的异常类型是否匹配,如果不能进行匹配,那么就会直接交给JVM来进行处理

3)如果没有找到匹配的异常类型,就会将异常向上传递到上层调用者;

4)无论是否找到匹配的异常类型,finally中的代码都会被执行掉,(在该方法结束之前执行)

5)如果上层调用者也没有处理了的异常,就会继续执行向上传递,一旦main()方法也没有合适的代码处理异常,就会交给JVM来进行处理,此时代码就会异常终止;

2.手动抛出异常

  public static int func(int x)
    {
        if(x==0)
        {
            throw new ArithmeticException("hh");
        }
        return 1;
        //return x/10;
    }
    public static void main(String[] args) {
        int x=func(0);
        System.out.println(x);
    }
无论返回多少,程序啥都不会进行打印
  public static void main(String[] args) {
        throw new ArithmeticException("111");
    }
  int x=0;
        if(x==0)
        {
            throw new UnsupportedOperationException("x==0我是不允许的");
        }

 3.处理受查异常

当一个代码中出现了受查异常,必须显式进行处理,如果一段代码可能会出现受查异常,那么也需要进行处理;

  public static void main(String[] args) throws FileNotFoundException {
        File file=new File("d:/22");
        Scanner scanner=new Scanner(file);
        System.out.println(scanner.nextLine());
    }

1)使用try catch进行包裹

  public static String readFile() {
     Scanner scan=null;
        try{
            File file=new File("d:/22");
            scan=new Scanner(file);
        }catch(FileNotFoundException e)
        {
            e.printStackTrace();
        }
        return scan.nextLine();

    }
    public static void main(String[] args) {
        String str=readFile();
        System.out.println(str);

    }

2)在方法名后面加上异常说明,相当于将处理动作交给上级调用者

 public static String readFile() throws FileNotFoundException {
        File file=new File("d:/22");
        Scanner scanner=new Scanner(file);
        return scanner.nextLine();
    }
    public static void main(String[] args) throws FileNotFoundException {
        String str=readFile();
    }

4.自定义异常

一个自定义异常继承了Exception就被称为受查异常,继承于RuntimeException就被称为非受查异常

   static class MyException extends Exception{       
       public MyException(String message) {          
           super(message);                           
       }                                             
   }                                                 
   static class MyException1 extends RuntimeException
       public MyException1(String message) {         
           super(message);                           
       }                                             
   }                                                 
   public static void func1(int x){                  
       if(x==0)                                      
       {                                             
           try {                                     
               throw new MyException("这是我自己抛出的异常");//
           } catch (MyException e) {                 
               e.printStackTrace();                  
           }                                         
       }                                             
                                                     
   }                                                 
   public static void func2(int x)                   
   {                                                 
       if(x==0){                                     
           throw new MyException1("x==0");//不需要进行try catch进行包裹         
       }                                             
   }                                                 

实例1:实现一个简单的用户登录功能

static  class NameException extends Exception{
      public NameException(String message)
      {
         super(message);
      }
   }
 static  class PasswordException extends Exception
   {
      public PasswordException(String message)
      {
         super(message);
      }
   }
   private static final String name="李佳伟";
   private static final String password="12503487";
   public static void login(String name, String password) throws NameException, PasswordException {
      if(!test.name.equals(name))
      {
         throw new NameException("您输入的用户名错误");
      }
      if(!test.password.equals(password))
      {
         throw new PasswordException("您输入的密码是错误的");
      }
      System.out.println("登陆成功");
   }
   public static void main(String[] args) {
      try {
         login("李佳伟","12503487");
      } catch (NameException e) {
         e.printStackTrace();
      } catch (PasswordException e) {
         e.printStackTrace();
      }
   }

示例2:使用while循环来进行类似于恢复异常的处理行为,他将不断重复,直到程序不在抛出异常

 public static void main(String[] args) {
      int i = 0;
      while (i < 15) {
         try {
            if (i < 10) {
               throw new UnsupportedOperationException("i现在还小于10");
            }
         } catch (UnsupportedOperationException e) {
            e.printStackTrace();
            System.out.println("第" + i + "次");
            i++;
         }
      }
   }

猜你喜欢

转载自blog.csdn.net/weixin_61518137/article/details/125096972