zoukankan      html  css  js  c++  java
  • 异常

    异常是什么?

    1.异常模拟的是现实世界中的“不正常”事件

    2.java中采用“类”去模拟异常

    3.类是可以创建对象的

    异常的作用?

    程序发生异常事件后(比如空指针),为我们输出详细的信息,程序员通过这个信息,可以对程序进行一些处理,使程序更加健壮

    前面的代码发生了异常并且没有处理,那么下面的代码也不会执行了,直接退出JVM

    public class Test01 {
    
        public static void main(String[] args) {
            int m = 10 ; 
            int n = 0 ;
            
            System.out.println(m/n);
            
            System.out.println("hello world"); //不会输出
        }
        
    }

    如果捕获异常后可以,比如

    package exceptiontest;
    
    public class Test01 {
    
        public static void main(String[] args) {
            int m = 10 ; 
            int n = 0 ;
            
            try {
                System.out.println(m/n);
            } catch (Exception e){
                e.printStackTrace();
            }
            
            System.out.println("hello world"); 
        }
        
    }

    java.lang.ArithmeticException: / by zero
    at exceptiontest.Test01.main(Test01.java:10)
    hello world

    如果使用throws来抛出异常,则hello world不会输出,如

    package exceptiontest;
    
    public class Test03 {
        
        public static void main(String args[] ) throws Exception{
            int m = 10;
            int n = 0;
            System.out.println(m/n);
            System.out.println("hello world "); //不会输出
        }
    }

    异常继承结构

    Throwable:所有异常都是可以抛出的

    Error:java程序运行中如果出现了错误,错误是不能处理的,只能退出JVM,例如StackOverflowError。Error类描述了java运行时系统的内部错误和资源耗尽错误,这种情况很少出现。

    Exception是可以处理的,如果没有处理异常,则直接退出JVM

    RuntimeException:运行时异常,由程序错误导致的异常属于RuntimeException,而程序本身没问题,但由像I/O错误这类问题导致的异常属于其他异常,或者说编译时异常。可以说,如果出现RuntimeException,那么一定是你的问题,常见的有上面的ArithmeticException,NullPointerException等

    编译时异常:Exception所有的直接子类都是编译时异常,如IOException

    编译时异常和运行似乎异常

    所有的编译时异常,要求程序员在编写程序阶段必须对它进行处理,不处理的话,编译无法通过。有两种处理方式:捕捉(try catch ) 和声明抛出(在方法声明的位置上使用throws关键字抛出异常),出现几率比较高

    对于运行时异常,编写程序阶段不需要对其进行处理,出现几率比较低

    关于try{}catch{}语句块

     catch{.....}可以写多个,但是必须从上到下,从小(类型异常)到大(类型异常),最多只会执行1个catch{...},之后try{}catch{}语句块就结束了,然后将继续向下执行,throws可以抛出多个异常,用逗号隔开,而且没有大小顺序之分

    public class Test02 {
    
        public static void main(String[] args) {
            try {
                FileInputStream fis = new FileInputStream("D:/test.txt");//发生异常,
                //try{}中下面得语句将不再执行
                //JVM会自动创建一个FileNotFoundException类型的对象,将该对象的内存地址赋值给catch语句块中的e变量
                System.out.println("rererere");//不会输出
                
                fis.read();
            }catch (FileNotFoundException e){//e内存地址指向堆中那个对象是FileNotFoundException类型的事件
                System.out.println("文件未找到");
                //FileNotFoundException复写了toString方法
                System.out.println(e);
            }catch (IOException e){
                System.out.println("其他IO异常");
            }
            
            System.out.println("hello world");
        }
    
    }

    文件未找到
    java.io.FileNotFoundException: D: est.txt (系统找不到指定的文件。)
    hello world

    关于finally语句块

    1.finally可以直接和try语句块联用,如:try{}finally{}

    2.finally中的语句是一定会执行的

    public class Test04 {
    
        public static void main(String[] args) {
            try{
                System.out.println("try~");
                return;
            }finally{
                System.out.println("finally~");
            }
        }
    
    }

    输出:

    try~
    finally~

    只有一种情况finally语句块不会执行,那就是在finally语句块之前退出了JVM,如

    public class Test05 {
    
        public static void main(String[] args) {
            try{
                System.out.println("before exit....");
                System.exit(0); //退出JVM
                System.out.println("try.....");
            }finally {
                System.out.println("finally....");
            }
        }
    
    }

    输出:before exit....

    又一个例子

    public class Test06 {
    
        public static void main(String[] args) {
            int  i = fun();
            System.out.println("main..... i = " + i);
        }
        
        public static int fun(){
            int i = 0;
            try{
                i = 10;
                return i;
            }finally {
                i++;
                System.out.println("finally ..... i = " + i);
            }
        }
    }

    finally ..... i = 11
    main..... i = 10

    上面try{}中执行原理是这样的

    try{
                i = 10;
                int tmp = i;//创建一个临时变量来保存i,并返回这个值
                return tmp;
            }finally {
                i++;   //这里操作的是i而不是tmp
                System.out.println("finally ..... i = " + i);
            }

    final、finalize、finally的区别

    这几个完全没有关系哈OTZ

    1.final修饰的类无法被继承,修饰的方法无法被覆盖,修饰的局部变量一旦赋值不可再改变,修饰的成员变量需要手动赋值,另外,final和static修饰的变量称为常量

    2.finalize压根就不是关键字,是Object类里的一个方法的名字,垃圾回收器在回收java对象前会自动调用java调用java对象的finalize方法

    3.finally是异常机制中的finally语句块

    自定义异常

    1.编译时异常,直接继承Exception

    2.运行时异常,直接继承RuntimeException

    package exceptiontest;
    
    public class Test07 {
    
        public static void main(String[] args) {
            CustomerService cs = new CustomerService();
            try{
                cs.register("kobe");
            }catch (IllegalNameException e){
                System.out.println(e.getMessage());
            }
            System.out.println("yyyyy");
        }
    
    }
    
    class IllegalNameException extends Exception{
        //定义异常一般提供两个构造方法,嗯 这是套路
        public IllegalNameException(){
            
        }
        
        public IllegalNameException(String msg){
            super(msg);
        }
        
    }
    
    class CustomerService{
        public void register(String username) throws IllegalNameException{//里面异常,所有需要throws抛出告诉外面
            
            if (username.length() < 6){
                //创建异常对象,手动抛出,是throw不是throws,用的地方不同啊
                throw new IllegalNameException("用户名长度不能小于6");
            }
            
            System.out.println("注册成功!");
        }
    }

    用户名长度不能小于6
    yyyyy

    重写的方法不能比被重写的方法抛出更宽泛的异常

    举个栗子

    class A{
        public void fun(){
            
        }
    }
    class B extends A{
        @Override
        public void fun() throws Exception{
            //子类无法抛出比父类更多的异常
            super.fun();
        }
    }

    以上编译错误:

    Exception Exception is not compatible with throws clause in A.fun()

    再举个栗子

    class A{
        public void fun() throws FileNotFoundException{
            
        }
    }
    class B extends A{
        @Override
        public void fun() throws IOException{
            //编译错误,子类无法抛出比父类更大(宽)的异常
            super.fun();
        }
    }

    又一个栗子

    class A{
        public void fun() throws IOException{
            
        }
    }
    class B extends A{
        @Override
        public void fun() throws FileNotFoundException{
            //编译通过
        }
    }
  • 相关阅读:
    表格边框
    vue路由守卫
    移动端专用css
    原生js写的的浏览器历史记录
    有趣
    表格边框
    路由
    php安装
    curl
    case when
  • 原文地址:https://www.cnblogs.com/i-love-kobe/p/5927732.html
Copyright © 2011-2022 走看看