精华内容
下载资源
问答
  • Java异常及处理
    千次阅读
    2022-01-28 17:31:36

    一、概述

    程序出现了不正常的情况,分为两种

    第一种是编译时异常(非RuntimeException异常)

    第二种是运行时异常(RuntimeException异常)

    二、处理方式

    1、

    try {
        可能出现问题的代码
    }
    catch(异常名 变量) {
        针对问题的处理
    }
    finally {
        释放资源
    }

    注意:

    1)try不能单独出现

    2)后面必须添加catch或finally

    3)catch有一组括号是为了捕获异常

    4)catch可以存在多个(捕获异常时之间无任何继承关系,且需要从小到大捕获)

    5)finally只能有一个,且finally一定会执行

    6)一旦try里面出现了问题,就会在这里把问题跑出去,然后和catch里面的问题进行匹配,一旦有匹配,就执行catch中的处理,然后结束了try…catch

    7)能明确的异常尽量明确,不要用父类来处理。若平级关系的异常,不分前后,若出现父子关系,则父类必须在后面

    8)try里面的代码越少越好

    9)catch里面必须有内容,哪怕是一个简单的提示

    2、throws 异常类名

    注意:

    1)这个格式必须在方法的括号后面

    2)尽量不要在main方法上抛出异常

    三、编译时异常和运行时异常的区别

    1、编译时异常:Java程序必须显示处理,否则程序就会发生错误,无法进行编译

    2、运行时异常:无需显示处理,也可以和编译时异常一样处理

    四、异常中的方法(需要了解)

    public String getMessage();异常的消息字符串

    public String toString();返回异常的简单信息描述

    public StackTrace();获取异常类名和异常信息,以及异常出现在程序的位置,返回值void,把信息输出到控制台

    五、throw和throws的区别

    1、throws

    1)用在方法声明后面,跟的是异常类名

    2)可以跟多个异常类名,用逗号隔开

    3)表示抛出异常,由该方法的调用者来处理

    4)throws表示出异常的一种可能性,并不一定会发生这些异常

    2、throw

    1)用在方法体内,跟的是异常对象名

    2)只能抛出一个异常对象名

    3)表示抛出异常,有方法体内的语句处理

    4)throws是抛出异常,执行throw则一定抛出了某种异常

    六、如何处理异常

    1、原则:如果该功能内部可以将问题处理,用try,如果无法处理,则交给调用者处理,这时候用throws

    2、区别:后续程序需要继续运行就try,不需要继续运行则用throws

    七、finally的特点

    用于释放资源,在IO流操作和数据库操作中会见到

    八、final、finally、finalize的区别

    1、final:最终的意思,可以修饰类,成员变量,成员方法

    修饰类:类不能被继承

    修饰变量:变量是常量

    修饰方法:方法不能被重写

    2、finally:是异常处理的一部分,用于释放资源

    一般来说代码是肯定会执行,特殊情况在执行到finally之前JVM退出了

    3、finalize:是Object类的一个方法,用于垃圾回收

    九、自定义异常(构造方法:super(s))

    继承自Exception和RuntimeException

    十、异常注意事项

    1、子类重写父类方法时,子类的方法必须抛出相同的异常或者父类异常的子类

    2、如果父类抛出多个异常,子类重写父类时,只能抛出相同的异常或者他的子集,子类不能抛出父类没有的异常

    3、如果被重写的方法没有异常抛出,那么子类的方法绝对不可以抛出异常,如果子类方法内有异常发生,那么子类只能try,不能用throws

    注意:

    如果catch里面有return语句,请问finally里面的代码还会执行吗?如果有请问是在return前还是return后?

    会执行,在return前面执行且finally内的内容必定执行

    更多相关内容
  • java异常和错误类总结(必看篇)

    千次阅读 2021-03-07 06:29:00
    java异常和错误类总结最近由于考试和以前的面试经常会遇到java当中异常类的继承层次的问题,弄得非常头大,因为java异常实在是有点多,很难记下来,今天正好查了一些资料整理下来,希望对自己和大家有点帮助。...

    java异常和错误类总结

    最近由于考试和以前的面试经常会遇到java当中异常类的继承层次的问题,弄得非常头大,因为java的异常实在是有点多,很难记下来,今天正好查了一些资料整理下来,希望对自己和大家有点帮助。最开始的时候习惯用笔记本(手写的纸质的本子)记笔记,后来发现查阅的时候不是很方便,而且速度比较慢。后来改用notepad开始记,感觉效果挺棒,简单易用,没有花哨的东西。但是也有它的缺点,比如版式的整理,不能加入一些图片(往往图片特别是一些大纲是非常好的记忆学习方法)等等,于是尝试用markdown开始写,放到博客上以后查阅方便,也能让大家分享,一起学习进步。从开始学习计算机相关领域直到现在,非常感谢很多国内外大牛无私的分享,真的学到了很多,以后不断的学习知识的同时,以此自勉,也要多多写点东西和大家分享,欢迎指出不足和错误之处,一起学习。

    一、java异常和错误的主要类

    java异常分为异常和错误,exception和error,两个类,者这两个类都继承自throwable类,throwable是所有java异常的根。

    java所有的异常类包括throwable,exception,error都是类,所以都是可以实例化的(笔试经常会遇到)

    error:不能被程序很好处理的错误(cannot be handled reasonably by program)

    机器的内存不够了

    jvm崩溃了(是程序都有可能挂掉)

    线程挂掉了

    exception:可以被程序处理的(can be handled by program)

    io错误(键盘,磁盘)

    网络错误

    不合法的类型转换

    数组或者容器越界

    java的异常一般会分为运行时异常和非运行时异常

    运行时异常就是runtimeexception的所有子类

    非运行时异常就是exception的其他所有孩子类,比如ioexception,interruptedexception

    二、java异常结构图

    c5b3565168c54566f73c27cd97780a0e.png

    三、java异常详细的类层次结构

    java.lang包里面的所有异常

    java.lang.throwable (implements java.io.serializable)

    java.lang.error

    java.lang.assertionerror

    java.lang.linkageerror

    java.lang.bootstrapmethoderror

    java.lang.classcircularityerror

    java.lang.classformaterror

    java.lang.unsupportedclassversionerror

    java.lang.exceptionininitializererror

    java.lang.incompatibleclasschangeerror

    java.lang.abstractmethoderror

    java.lang.illegalaccesserror

    java.lang.instantiationerror

    java.lang.nosuchfielderror

    java.lang.nosuchmethoderror

    java.lang.noclassdeffounderror

    java.lang.unsatisfiedlinkerror

    java.lang.verifyerror

    java.lang.threaddeath

    java.lang.virtualmachineerror

    java.lang.internalerror

    java.lang.outofmemoryerror

    java.lang.stackoverflowerror

    java.lang.unknownerror

    java.lang.exception

    java.lang.clonenotsupportedexception

    java.lang.interruptedexception

    java.lang.reflectiveoperationexception

    java.lang.classnotfoundexception

    java.lang.illegalaccessexception

    java.lang.instantiationexception

    java.lang.nosuchfieldexception

    java.lang.nosuchmethodexception

    java.lang.runtimeexception

    java.lang.arithmeticexception

    java.lang.arraystoreexception

    java.lang.classcastexception

    java.lang.enumconstantnotpresentexception

    java.lang.illegalargumentexception

    java.lang.illegalthreadstateexception

    java.lang.numberformatexception

    java.lang.illegalmonitorstateexception

    java.lang.illegalstateexception

    java.lang.indexoutofboundsexception

    java.lang.arrayindexoutofboundsexception

    java.lang.stringindexoutofboundsexception

    java.lang.negativearraysizeexception

    java.lang.nullpointerexception

    java.lang.securityexception

    java.lang.typenotpresentexception

    java.lang.unsupportedoperationexception

    java.io包里的所有io异常

    ava.lang.exception

    java.io.ioexception

    java.io.charconversionexception

    java.io.eofexception

    java.io.filenotfoundexception

    java.io.interruptedioexception

    java.io.objectstreamexception

    java.io.invalidclassexception

    java.io.invalidobjectexception

    java.io.notactiveexception

    java.io.notserializableexception

    java.io.optionaldataexception

    java.io.streamcorruptedexception

    java.io.writeabortedexception

    java.io.syncfailedexception

    java.io.unsupportedencodingexception

    java.io.utfdataformatexception

    以上这篇java异常和错误类总结(必看篇)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持萬仟网。

    希望与广大网友互动??

    点此进行留言吧!

    展开全文
  • 002_Java语言的八大特性

    千次阅读 2020-04-28 09:50:26
    文章目录一、Java语言的特性 (开源、免费、跨平台、纯面向对象)1、简单性2、面向对象3、跨平台性/可移植性4、健壮性5、安全性6、 一、Java语言的特性 (开源、免费、跨平台、纯面向对象) 1、简单性 相对而言,C++...

    一、🔺Java语言的八大特性 (开源、免费、跨平台、纯面向对象)

    SUN公司对java的描述:
          “Java is a simple,object-oriented, distributed, interpreted, robust, secure, architecture neutral, portable, high-performance, multihreaded, and dynamic language”.
    翻译过来就是: “Java是一门简单的面向对象分布式解释性健壮的安全的结构中立的便捷的高性能的多线程的动态的语言”

    1、简单性

    相对而言,C++中有指针Java屏蔽了指针
                     C++支持多继承(复杂)Java使用接口替代多继承

    注:Java语言底层是C++实现的,不是C语言。


    2、🔺面向对象

    “Everything is Object.” (万事万物皆为对象)

    纯面向对象封装、继承、多态、抽象), 类机制
    更符合人的思维模式,更容易理解


    3、🔺跨平台性/可移植性

    “Compile Once, Run Anywhere.” (一次编译,处处运行)


    4、分布式

    操作分布:在多个不同主机上布置相关操作
         数据分布:将数据分别存放在多个网络中不同主机上,借助URL(统一资源定位)访问网络对象,访问方式和本地系统相似。
    ② 基本的Java程序有网络应用编程接口(java.net)
    RMI(Remote Method Invocation 远程方法调用)和EJB(Enterprise Java Beans 企业Java Beans)可用于创建分布式应用程序,可通过互联网任何机器调用方法访问文件。

    扩展:
    👉 JavaRMI_百度百科
    👉 EJB_百度百科


    5、多线程

    ① 多线程:指允许一个应用程序同时存在两个或两个以上的线程,用于支撑事务并发多任务处理
    ② 多线程机制使应用程序在同一时间并发执行多项任务。Java语言提供多线程之间的同步机制,保证不同线程正确共享数据,使程序具有更好的交互性和实时性。
    Thread类用于操作线程,负责、启动、运行、终止线程,并检查线程状态。

    扩展:
    👉 多线程_百度百科


    6、健壮性

    🔺自动垃圾回收机制(GC机制)、强类型机制、异常处理…


    7、安全性

    没有显示指针,Java程序在JVM(Java虚拟机)中运行。
    Java删除指针和内容释放等语法,有效避免了非法操作内存。
    编译时需要进行Java语法的检查,保证无误后生成Java类(.java源文件 编译成 .class字节码文件),运行Java类时需要类装载器(ClassLoader)载入,并由字节码校验器校验之后,交由安全管理器检查具体操作后才能运行。
    ③ 为增强安全性,java提供防止恶意代码攻击的安全机制(数组边界检测、ByteCode校验等)。
    ④ Java还可编写防病毒和可修复系统。


    8、高性能

    先编译后解释


    🍅🍅🍅 以往文章 👇

    001_Java语言发展历程
    003_浅析JDK、JRE、JVM的区别和联系
    004_JDK的下载安装与环境变量的配置
    005_常用DOS命令
    006_Java关键字、标识符、注释
    007_Java八大基本数据类型
    008_Java类型转换
    009_Java运算符
    010_Java流程控制语句

    展开全文
  • 最全最详细的Java异常处理机制

    千次阅读 2022-01-27 11:21:36
    一、异常概述与异常体系结构 异常概述 在使用计算机语言进行项目开发的过程中,即使程序员把代码写得尽善尽美,在系统的运行过程中仍然会遇到一些问题,因为...Java程序在执行过程中所发生的异常事件可分为两类: ...

    一、异常概述与异常体系结构

    异常概述

            在使用计算机语言进行项目开发的过程中,即使程序员把代码写得尽善尽美,在系统的运行过程中仍然会遇到一些问题,因为很多问题不是靠代码能够避免的,比如:客户输入数据的格式,读取文件是否存在,网络是否始终保持通畅等等。
        
            程序运行时,发生的不被期望的事件,它阻止了程序按照程序员的预期正常执行,这就是异常(开发过程中的语法错误和逻辑错误不是异常)。

            Java程序在执行过程中所发生的异常事件可分为两类:
            Error:Java虚拟机无法解决的严重问题。如:JVM系统内部错误、资源耗尽等严重情况。比如:StackOverflowError(栈溢出)和OOM(内存溢出)。一般不编写针对性的代码进行处理。
            Exception: 其它因编程错误或偶然的外在因素导致的一般性问题,可以使用针对性的代码进行处理。例如:
                空指针访问
                试图读取不存在的文件
                网络连接中断
                数组角标越界

    Error示例代码:

    public class ErrorTest {
        public static void main(String[] args) {
            /*
             * 1、栈溢出:java.lang.StackOverflowError
             *   原因 : 函数调用栈太深了,注意代码中是否有了循环调用方法而无法退出的情况
             *   StackOverflowError 是一个java中常出现的错误:在jvm运行时的数据区域中有一个java虚拟机栈,当执行java方法时会进行压栈弹栈的操作。在栈中会保存局部变量,操作数栈,方法出口等等。jvm规定了栈的最大深度,当执行时栈的深度大于了规定的深度,就会抛出StackOverflowError错误。
             * */
            main(args);
    
            /*
             * 2、堆溢出:java.lang.OutOfMemoryError
             *   原因:Java中所有的对象都存储在堆中,通常如果JVM无法再分配新的内存,内存耗尽,垃圾回收无法及时回收内存,就会抛出OutOfMemoryError。
             * */
            Integer[] arr = new Integer[1024 * 1024 * 1024];
    
        }
    }

    Exception示例代码:

    import java.io.FileInputStream;
    
    public class ExceptionTest {
        public static void main(String[] args) {
            /*
             * 1、运行时异常:java.lang.ArithmeticException
             *  原因:ArithmeticException
             * */
            int a = 10;
            int b = 0;
            System.out.println(a / b);
    
            /*
             * 2、编译期异常:java.io.FileNotFoundException
             *   原因:文件找不到异常通常是两种情况:1、系统找不到指定的路径 2、拒绝访问(指定的是目录时,就会报拒绝访问异常)
             * */
            FileInputStream fis = new FileInputStream("a.txt");
    
        }
    }

            异常发生时,是任程序自生自灭,立刻退出终止,还是输出错误给用户?或者用C语言风格:用函数返回值作为执行状态?

            Java提供了更加优秀的解决办法:异常处理机制。异常处理机制能让程序在异常发生时,按照代码的预先设定的异常处理逻辑,针对性地处理异常,让程序尽最大可能恢复正常并继续执行,且保持代码的清晰。

            Java中的异常可以是函数中的语句执行时引发的,也可以是程序员通过throw 语句手动抛出的,只要在Java程序中产生了异常,就会用一个对应类型的异常对象来封装异常,JRE就会试图寻找异常处理程序来处理异常。
     
            Throwable类是Java异常类型的顶层父类,一个对象只有是 Throwable 类的(直接或者间接)实例,他才是一个异常对象,才能被异常处理机制识别。JDK中内建了一些常用的异常类,我们也可以自定义异常。

    异常体系结构

            Java标准库内建了一些通用的异常,这些类以Throwable为顶层父类。

            Throwable又派生出Error类和Exception类。

            错误:Error类以及它的子类的实例,代表了JVM本身的错误。错误不能被程序员通过代码处理,Error很少出现。因此,程序员应该关注Exception为父类的分支下的各种异常类。

            异常:Exception以及它的子类,代表程序运行时发生的各种不期望发生的事件。可以被Java异常处理机制使用,是异常处理的核心。

    Error和Exception的区别:

            Error和Exception都有一个共同的根类是Throwable类。
        
            Error是系统中的错误,程序员是不能改变的和处理的,一般是指与虚拟机相关的问题,如系统崩溃,虚拟机错误,内存空间不足,方法调用栈溢等。对于这类错误的导致的应用程序中断,仅靠程序本身无法恢复和和预防,遇到这样的错误,建议让程序终止。因此我们编写程序时不需要关心这类错误。
        
            Exception,也就是我们经常见到的一些异常情况,表示程序可以处理的异常,可以捕获且可能恢复。遇到这类异常,应该尽可能处理异常,使程序恢复运行,而不应该随意终止异常。

    异常体系结构图:

    异常分类

            总体上我们根据Javac对异常的处理要求,将异常类分为2类。
        
            我们常说的异常是狭义上的:就是指Exception及其子类,但是广义上的异常是包括Exception和Error;

            Java的异常(包括Exception和Error)从广义上分为检查异常(checked exceptions)和非检查的异常(unchecked exceptions)。

            其中根据Exception异常进行划分,可分为运行时异常和非运行时异常。

            需要明确的是:检查和非检查是对于javac来说的,这样就很好理解和区分了。

    检查异常

    What:什么是检查异常(checked exception)?

            就是编译器要求你必须处置的异常。不知道你编程的时候有没有遇到过,你写的某段代码,编译器要求你必须要对这段代码try...catch,或者throws exception,如果你遇见过,没错,这就是检查异常,也就是说,你代码还没运行呢,编译器就会检查你的代码,会不会出现异常,要求你对可能出现的异常必须做出相应的处理。

            javac强制要求程序员为这样的异常做预备处理工作(使用try...catch...finally或者throws)。在方法中要么用try-catch语句捕获它并处理,要么用throws子句声明抛出它,否则编译不会通过。这样的异常一般是由程序的运行环境导致的。因为程序可能被运行在各种未知的环境下,而程序员无法干预用户如何使用他编写的程序,于是程序员就应该为这样的异常时刻准备着。如SQLException , IOException,ClassNotFoundException 等。

            比如:我们调用日期格式化类解析字符串的时候;

    How:怎样处理检查异常(checked exception)?

            1、继续抛出,消极的方法,一直可以抛到java虚拟机来处理,就是通过throws Exception抛出。

            2、用try...catch捕获

            注意,对于检查的异常必须处理,或者必须捕获或者必须抛出

    Where:检查异常有哪些呢?

            除了RuntimeException与其子类,以及错误(Error),其他的都是检查异常(绝对的大家族)。

    非检查异常

    What:什么是非检查异常(unchecked exceptions)?

            编译器不要求强制处置的异常,虽然你有可能出现错误,但是编译器不会在编译的时候检查,没必要,也不可能。

            javac在编译时,不会提示和发现这样的异常,不要求在程序处理这些异常。所以如果愿意,我们可以编写代码处理(使用try...catch...finally)这样的异常,也可以不处理。

            对于这些异常,我们应该修正代码,而不是去通过异常处理器处理。这样的异常发生的原因多半是代码写的有问题。如除0错误ArithmeticException,错误的强制类型转换错误ClassCastException,数组索引越界ArrayIndexOutOfBoundsException,使用了空对象NullPointerException等等。

    How:对非检查的异常(unchecked exception )怎样处理?

            1、用try...catch捕获
            2、继续抛出
            3、不处理
            4、通过代码处理

            一般我们是通过代码处理的,因为你很难判断会出什么问题,而且有些异常你也无法运行时处理,比如空指针,需要人手动的去查找。

            而且,捕捉异常并处理的代价远远大于直接抛出。

    Why:为什么有非检查异常?

            你想想非检查异常都有哪些?NullPointerException,IndexOutOfBoundsException,VirtualMachineError等,这些异常你编译的时候检查吗?再说了,明明可以运行时检查,都在编译的时候检查,你写的代码还能看吗?而且有些异常只能在运行时才能检查出来,比如空指针,堆溢出等。

    Where:非检查异常有哪些?

            RuntimeException与其子类,以及错误(Error)。

    Exception异常划分

            Exception异常进行划分,它可分为运行时异常和编译期异常。

            运行时异常:
                    是RuntimeException类及其子类异常,如NullPointerException(空指针异常)、IndexOutOfBoundsException(下标越界异常)等,这些异常是非检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。

                    运行时异常的特点是Java编译器不会检查它,也就是说,当程序中可能出现这类异常,即使没有用try-catch语句捕获它,也没有用throws子句声明抛出它,也会编译通过。

            编译期异常:
                    是RuntimeException以外的异常,类型上都属于Exception类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如IOException、SQLException等以及用户自定义的Exception异常,一般情况下不要自定义检查异常。

    二、初识异常与常见异常

    初识异常

            下面的代码会演示2个异常类型:ArithmeticException 和 InputMismatchException。

            前者由于整数除0引发,后者是输入的数据不能被转换为int类型引发。

    import java.util.Scanner;
    
    public class AllDemo {
        public static void main(String[] args) {
            System.out.println("----欢迎使用命令行除法计算器----");
            CMDCalculate();
        }
    
        public static void CMDCalculate() {
            Scanner scan = new Scanner(System.in);
            int num1 = scan.nextInt();
            int num2 = scan.nextInt();
            int result = devide(num1, num2);
            System.out.println("result:" + result);
            scan.close();
        }
    
        public static int devide(int num1, int num2) {
            return num1 / num2;
        }
    }
    
    /*****************************************
    ----欢迎使用命令行除法计算器----
    2
    0
    Exception in thread "main" java.lang.ArithmeticException: / by zero
    	at AllDemo.devide(AllDemo.java:19)
    	at AllDemo.CMDCalculate(AllDemo.java:13)
    	at AllDemo.main(AllDemo.java:6)
    
    ----欢迎使用命令行除法计算器----
    ----欢迎使用命令行除法计算器----
    1
    r
    Exception in thread "main" java.util.InputMismatchException
    	at java.util.Scanner.throwFor(Scanner.java:864)
    	at java.util.Scanner.next(Scanner.java:1485)
    	at java.util.Scanner.nextInt(Scanner.java:2117)
    	at java.util.Scanner.nextInt(Scanner.java:2076)
    	at AllDemo.CMDCalculate(AllDemo.java:12)
    	at AllDemo.main(AllDemo.java:6)
    *****************************************/

            异常是在执行某个函数时引发的,而函数又是层级调用,形成调用栈的,因为,只要一个函数发生了异常,那么他的所有的caller都会被异常影响。当这些被影响的函数以异常信息输出时,就形成的了异常追踪栈。

            异常最先发生的地方,叫做异常抛出点。

            从上面的例子可以看出,当devide函数发生除0异常时,devide函数将抛出ArithmeticException异常,因此调用它的CMDCalculate函数也无法正常完成,因此也发送异常,而CMDCalculate的caller——main 因为CMDCalculate抛出异常,也发生了异常,这样一直向调用栈的栈底回溯。这种行为叫做异常的冒泡,异常的冒泡是为了在当前发生异常的函数或者这个函数的caller中找到最近的异常处理程序。由于这个例子中没有使用任何异常处理机制,因此异常最终由main函数抛给JRE,导致程序终止。

            上面的代码不使用异常处理机制,也可以顺利编译,因为2个异常都是非检查异常。但是下面的例子就必须使用异常处理机制,因为异常是检查异常。

            代码中我选择使用throws声明异常,让函数的调用者去处理可能发生的异常。但是为什么只throws了IOException呢?因为FileNotFoundException是IOException的子类,在处理范围内。

    import java.io.FileInputStream;
    import java.io.IOException;
    
    public class ExceptionTest {
        public void testException() throws IOException {
            //FileInputStream的构造函数会抛出FileNotFoundException
            FileInputStream fileIn = new FileInputStream("E:\\a.txt");
    
            int word;
            //read方法会抛出IOException
            while ((word = fileIn.read()) != -1) {
                System.out.print((char) word);
            }
            //close方法会抛出IOException
            fileIn.close();
        }
    }

    常见异常

            java.lang.RuntimeException: 运行时异常
                    ClassCastException: 类类型转换异常,当试图将对象强制转换为不是实例的子类时,抛出该异常;
                    ArrayIndexOutOfBoundsException: 数组下标越界异常,当你使用不合法的索引访问数组时会抛出该异常;
                    NullPointerException: 空指针异常,通过null进行方法和属性调用会抛出该异常;
                    ArithmeticException: 算术运算异常,除数为0,抛出该异常;
                    NumberFormatException: 数字转换异常,当试图将一个String转换为指定的数字类型,而该字符串确不满足数字类型要求的格式时,抛出该异常;
                    InputMismatchException: 输入不匹配异常,输入的值数据类型与设置的值数据类型不能匹配。
            ...

    import java.io.FileInputStream;
    import java.io.IOException;
    import java.util.Date;
    import java.util.Scanner;
    
    public class ExceptionTest {
        //ClassCastException
        public void test1() {
            Object obj = new Date();
            String str = (String) obj;
        }
    
        //IndexOutOfBoundsException
        public void test2() {
            //ArrayIndexOutOfBoundsException
            int[] arr = new int[10];
            System.out.println(arr[10]);
    
            //StringIndexOutOfBoundsException
            String str = "abc";
            System.out.println(str.charAt(3));
        }
    
        //NullPointerException
        public void test3() {
            int[] arr = null;
            System.out.println(arr[3]);
    
            String str = "abc";
            str = null;
            System.out.println(str.charAt(0));
        }
    
        //ArithmeticException
        public void test4() {
            int a = 10;
            int b = 0;
            System.out.println(a / b);
        }
    
        //NumberFormatException
        public void test5() {
            String str = "123";
            str = "abc";
            int num = Integer.parseInt(str);
        }
    
        //InputMismatchException
        public void test6() {
            Scanner scanner = new Scanner(System.in);
            int score = scanner.nextInt();
            System.out.println(score);
            scanner.close();
        }
    }

            java.io.IOExeption: 输入输出异常
                    FileNotFoundException: 文件找不到异常,通常是两种情况:1、系统找不到指定的路径 2、拒绝访问(指定的是目录时,就会报拒绝访问异常)
                    EOFException: 文件已结束异常,抛出EOFException一定是因为连接断了还在继续read;

            java.lang.ClassNotFoundException: 类找不到异常,当我们通过配置文件去查找一个类的时候,如果配置路径写错,就会抛出该异常,比如:web.xml文件中根本就不存在该类的配置或者配置的路径写错;(比较常见)
            
            java.sql.SQLException: SQL异常,数据库的各种信息的异常;

    import java.io.File;
    import java.io.FileInputStream;
    
    public class ExceptionTest {
        
        public void test7() {
            File file = new File("hello.txt");
            FileInputStream fis = new FileInputStream(file);
    
            int data = fis.read();
            while (data != -1) {
                System.out.print((char) data);
                data = fis.read();
            }
    
            fis.close();
        }
    
    }

    三、异常处理的处理机制

            在编写程序时,经常要在可能出现错误的地方加上检测的代码,如进行x/y运算时,要检测分母为0,数据为空,输入的不是数据而是字符等。过多的if-else分支会导致程序的代码加长、臃肿,可读性差。因此采用异常处理机制。    

            在编写代码处理异常时,对于检查异常/非检查异常,都有2种不同的处理方式:
                    1、使用try...catch...finally语句块处理它。
                    2、在函数签名中使用throws 声明交给函数调用者caller去解决。
        
            比如现有一辆车,这个车你可以是方法,这辆车在可能存在各种风险,那么对于这些风险的处理方式,就相当于异常的处理方式:
            1、使用try...catch...finally语句块处理它。
                    我们把这辆车可能出现的问题都考虑清楚了,并提供了备选方案(出现问题怎么做),如果没有出现问题,那么用不到备选方案;
                    如果出现了问题,根据问题去找对应的备选方案,以保证车的正常运行;
                    如果出现了问题,但是又没备选方案,那么车就跑不了;
            2、在函数签名中使用throws 声明交给函数调用者caller去解决。
                    我知道车可能又问题,但是我不处理,谁来使用了,告诉调用者,这里可能有问题;
                    那么调用者可以处理这个问题,也可以不处理;如果它不处理,还是会出现问题,如果处理了,肯定没问题;
                    A -》 B -》 C

            Java采用的异常处理机制,是将异常处理的程序代码集中在一起,与正常的程序代码分开,使得程序简洁、优雅,并易于维护。

            Java提供的是异常处理的抓抛模型。
        
            Java程序的执行过程中如出现异常,会生成一个异常类对象,该异常对象将被提交给Java运行时系统,这个过程称为抛出(throw)异常。

            异常对象的生成:
                    由虚拟机自动生成:程序运行过程中,虚拟机检测到程序发生了问题,如果在当前代码中没有找到相应的处理程序,就会在后台自动创建一个对应异常类的实例对象并抛出——自动抛出。
                    由开发人员手动创建:Exception exception = new ClassCastException();——创建好的异常对象不抛出对程序没有任何影响,和创建一个普通对象一样。

            异常的抛出机制:
                    如果一个方法内抛出异常,该异常对象会被抛给调用者方法中处理。如果异常没有在调用者方法中处理,它继续被抛给这个调用方法的上层方法。这个过程将一直继续下去,直到异常被处理。这一过程称为捕获(catch)异常。
                    如果一个异常回到main()方法,并且main()也不处理,则程序运行终止。
                    程序员通常只能处理Exception,而对Error无能为力。

    异常处理机制一:try-catch-finally

    	语法格式:
            try{
                ...... //可能产生异常的代码
            }
            catch( ExceptionName1 e ){
                ...... //当产生ExceptionName1型异常时的处置措施
            }
            catch( ExceptionName2 e ){
                ...... //当产生ExceptionName2型异常时的处置措施
            }
            [ finally{
                ...... //无论是否发生异常,都无条件执行的语句
            } ]
    
    	语法解释:
    		try:
    			捕获异常的第一步是用try{…}语句块选定捕获异常的范围,将可能出现异常的代码放在try语句块中。
    			如果发生异常,则尝试去匹配catch块,catch块可以有多个(因为try块可以出现多个不同类型异常);
    			如果执行完try不管有没有发生异常,则接着去执行finally块和finally后面的代码(如果有的话)。			
    		catch (Exceptiontype e):
    			在catch语句块中是对异常对象进行处理的代码。每个try语句块可以伴随一个或多个catch语句,用于处理可能产生的不同类型的异常对象。
    			每一个catch块用于捕获并处理一个特定的异常,或者这异常类型的子类。Java可以将多个异常声明在一个catch中。 catch(Exception1 | Exception2 | Exception3 e)
    			catch后面的括号定义了异常类型和异常参数。如果异常与之匹配且是最先匹配到的,则虚拟机将使用这个catch块来处理异常。
    			在catch块中可以使用这个块的异常参数来获取异常的相关信息。异常参数是这个catch块中的局部变量,其它块不能访问。与其它对象一样,可以访问一个异常对象的成员变量或调用它的方法。
    				①、getMessage() 获取异常信息,返回字符串。
    				②、printStackTrace() 获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void。
    			如果当前try块中发生的异常在后续的所有catch中都没捕获到,则先去执行finally,然后到这个函数的外部caller中去匹配异常处理器。
    			如果try中没有发生异常,则所有的catch块将被忽略。
    			注意:如果明确知道产生的是何种异常,可以用该异常类作为catch的参数;也可以用其父类作为catch的参数。比如:可以用 ArithmeticException 类作为参数的地方,就可以用RuntimeException类作为参数,或者用所有异常的父类Exception类作为参数。但不能是与ArithmeticException类无关的异常,如NullPointerException(catch中的语句将不会执行)。
    
    		finally:
    			finally块通常是可选的。捕获异常的最后一步是通过finally语句为异常处理提供一个统一的出口,使得在控制流转到程序的其它部分以前,能够对程序的状态作统一的管理。
    			不论在try代码块中是否发生了异常事件,catch语句是否执行,catch语句是否有异常,catch语句中是否有return,finally块中的语句都会被执行。
    			一个try至少要有一个catch块,否则, 至少要有1个finally块。但是finally不是用来处理异常的,finally不会捕获异常。
    			finally主要做一些清理工作,如流的关闭,数据库连接的关闭等。 
    public class Test_Input_01 {
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            /*
    		 * 当我们只写一个try{}的时候,会报错:
    		 * 	Syntax error, insert "Finally" to complete TryStatement
    		 * 	语法错误,插入“Finally”来完成Try块
    		 * 
    		 * 总结: try不能单独存在,必须结合catch或finally来使用
    		 * 	try块中没有异常,会执行finally(如果有)
    		 *  try块中有异常,会执行对应的catch块(如果有),try中异常发生点之后的代码将不会执行
    		 */
            try{
                //try块中放可能发生异常的代码。
                //如果执行完try且不发生异常,则接着去执行finally块和finally后面的代码(如果有的话)。
                //如果发生异常,则尝试去匹配catch块。异常点之后的代码不会运行
    
                //这行代码有可能出错
                int num1 = sc.nextInt(); //这行代码如果出现异常,那么后面的输出语句就不执行
    
                int num2 = sc.nextInt();
    
                System.out.println(num1+"\t"+num2);
    
                System.out.println(num1/num2);
    
    
                String str = null;
                System.out.println(str.charAt(0));
    
            }catch(InputMismatchException | NullPointerException e) { 
                // catch(异常对象)	当异常发生了,catch就会捕获对应的异常
                // 每一个catch块用于捕获并处理一个特定的异常,或者这异常类型的子类。Java7中可以将多个异常声明在一个catch中。 catch(Exception1 | Exception2 | Exception3 e)
                // catch后面的括号定义了异常类型和异常参数。如果异常与之匹配且是最先匹配到的,则虚拟机将使用这个catch块来处理异常。
                // 在catch块中可以使用这个块的异常参数来获取异常的相关信息。异常参数是这个catch块中的局部变量,其它块不能访问。
                // 如果当前try块中发生的异常在后续的所有catch中都没捕获到,则先去执行finally,然后到这个函数的外部caller中去匹配异常处理器。
                // 如果try中没有发生异常,则所有的catch块将被忽略。
                System.out.println("catch块 - try里面发生了异常 - 空指针和输入不匹配异常都走这个Catch");
            }catch(java.lang.ArithmeticException e){
                e.getMessage();
                System.out.println("算数异常:除数不能为0");
    
            }catch(Exception e){
                System.out.println("程序发生未知异常");
            }finally {
                // finally块通常是可选的。
                // 无论异常是否发生,异常是否匹配被处理,finally都会执行。
                // 一个try至少要有一个catch块,否则, 至少要有1个finally块。但是finally不是用来处理异常的,finally不会捕获异常。
                // finally主要做一些清理工作,如流的关闭,数据库连接的关闭等。 
                System.out.println("finally块");
            }
    
            System.out.println("异常捕获之后的代码");
        }
    }	

    需要注意的地方

            1、try块中的局部变量和catch块中的局部变量(包括异常变量),以及finally中的局部变量,他们之间不可共享使用。

            2、每一个catch块用于处理一个异常。异常匹配是按照catch块的顺序从上往下寻找的,只有第一个匹配的catch会得到执行。匹配时,不仅运行精确匹配,也支持父类匹配,因此,如果同一个try块下的多个catch异常类型有父子关系,应该将子类异常放在前面,父类异常放在后面,这样保证每个catch块都有存在的意义。

            3、java中,异常处理的任务就是将执行控制流从异常发生的地方转移到能够处理这种异常的地方去。也就是说:当一个函数的某条语句发生异常时,这条语句的后面的语句不会再执行,它失去了焦点。执行流跳转到最近的匹配的异常处理catch代码块去执行,异常被处理完后,执行流会接着在“处理了这个异常的catch代码块”后面接着执行。

            有的编程语言当异常被处理后,控制流会恢复到异常抛出点接着执行,这种策略叫做:resumption model of exception handling(恢复式异常处理模式)

            而Java则是让执行流恢复到处理了异常的catch块后接着执行,这种策略叫做:termination model of exception handling(终结式异常处理模式)

    public static void main(String[] args){
        try {
            foo();
        }catch(ArithmeticException ae) {
            System.out.println("处理异常");
        }
    }
    public static void foo(){
        int a = 5/0;  //异常抛出点
        System.out.println("Look me!!!");  //不会执行
    }

            finally块不管异常是否发生,只要对应的try执行了,则它一定也执行。只有一种方法让finally块不执行:System.exit()。因此finally块通常用来做资源释放操作:关闭文件,关闭数据库连接等等。

            良好的编程习惯是:在try块中打开资源,在finally块中清理释放这些资源。

            需要注意的地方:

            1、finally块没有处理异常的能力。处理异常的只能是catch块。

            2、在同一try...catch...finally块中 ,如果try中抛出异常,且有匹配的catch块,则先执行catch块,再执行finally块。如果没有catch块匹配,则先执行finally,然后去外面的调用者中寻找合适的catch块。

            3、在同一try...catch...finally块中 ,try发生异常,且匹配的catch块中处理异常时也抛出异常,那么后面的finally也会执行:首先执行finally块,然后去外围调用者中寻找合适的catch块。

            这是正常的情况,但是也有特例。关于finally有很多恶心,偏、怪、难的问题.

            具体在最后一节:finally块和return 讲解

    不捕获异常时的情况:

            前面使用的异常都是RuntimeException类或是它的子类,这些类的异常的特点是:即使没有使用try和catch捕获,Java自己也能捕获,并且编译通过( 但运行时会发生异常使得程序运行终止 )。

            如果抛出的异常是IOException等类型的非运行时异常,则必须捕获,否则编译错误。也就是说,我们必须处理编译时异常,将异常进行捕捉,转化为运行时异常。

    import java.io.*;
    
    public class IOExp {
        public static void main(String[] args) {
            try {
                FileInputStream in = new FileInputStream("hello.txt");
                int b;
                b = in.read();
                while (b != -1) {
                    System.out.print((char) b);
                    b = in.read();
                }
                in.close();
            } catch (IOException e) {
                System.out.println(e);
            } finally {
                System.out.println(" It’s ok!");
            }
        }
    }

    异常处理机制二:throws

            throws是另一种处理异常的方式,它不同于try...catch...finally,throws仅仅是将函数中可能出现的异常向调用者声明,而自己则不具体处理。

            throws声明:如果一个方法内部的代码会抛出检查异常(checked exception),而方法自己又没有完全处理掉或并不能确定如何处理这种异常,则javac保证你必须在方法的签名上使用throws关键字声明这些可能抛出的异常,表明该方法将不对这些异常进行处理,而由该方法的调用者负责处理,否则编译不通过。

            在方法声明中用throws语句可以声明抛出异常的列表,throws后面的异常类型可以是方法中产生的异常类型,也可以是它的父类。

            采取这种异常处理的原因可能是:方法本身不知道如何处理这样的异常,或者说让调用者处理更好,调用者需要为可能发生的异常负责。

            语法格式:
            修饰符 返回值类型 方法名() throws ExceptionType1 , ExceptionType2 ,ExceptionTypeN{ 
                //方法内部可以抛出 ExceptionType1 , ExceptionType2 ,ExceptionTypeN 类的异常,或者他们的子类的异常对象。
            }

    import java.io.*;
    
    public class ThrowsTest {
        public static void main(String[] args) {
            ThrowsTest t = new ThrowsTest();
            try {
                t.readFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        public void readFile() throws IOException {
            FileInputStream in = new FileInputStream("hello.txt");
            int b;
            b = in.read();
            while (b != -1) {
                System.out.print((char) b);
                b = in.read();
            }
            in.close();
        }
    }

    四、手动抛出异常:throw

            Java异常类对象除在程序执行过程中出现异常时由系统自动生成并抛出,也可根据需要使用人工创建并抛出。

            首先要生成异常类对象,然后通过throw语句实现抛出操作(提交给Java运行环境)。
                    throw exceptionObject

            程序员也可以通过throw语句手动显式的抛出一个异常。throw语句的后面可以抛出的异常必须是Throwable或其子类的实例。下面的语句在编译时将会产生语法错误:
                    throw new String("你抛我试试.");

            throw 语句必须写在函数中,执行throw 语句的地方就是一个异常抛出点,它和由JRE自动形成的异常抛出点没有任何差别。

    public class StudentTest {
        public static void main(String[] args) {
            try {
                Student s = new Student();
                s.regist(-1001);
                System.out.println(s);
            } catch (Exception e) {
                System.out.println(e.getMessage());
            }
        }
    }
    
    class Student {
        private int id;
    
        public void regist(int id) throws Exception {
            if (id > 0) {
                this.id = id;
            } else {
                // System.out.println("您输入的数据非法!");
    
                //手动抛出异常对象
                // throw new RuntimeException("您输入的数据非法!");
                throw new Exception("您输入的数据非法!");
    
                //错误的
                // throw new String("不能输入负数");
            }
    
        }
    
        @Override
        public String toString() {
            return "Student [id=" + id + "]";
        }
    }

    throws和throw的区别:

            throw是语句抛出一个异常。
                    语法:throw (异常对象);
                        throw e;

            throws是方法可能抛出异常的声明。(用在声明方法时,表示该方法可能要抛出异常)
                    语法:[(修饰符)](返回值类型)(方法名)([参数列表])[throws(异常类)]{......}
                        public void doA(int a) throws Exception1,Exception3{......}

            throw语句用在方法体内,表示抛出异常,由方法体内的语句处理。
            throws出现在方法函数头,表示在抛出异常,由该方法的调用者来处理。

            throws主要是声明这个方法会抛出这种类型的异常,使它的调用者知道要捕获这个异常。
            throw是具体向外抛异常的动作,所以它是抛出一个异常实例。

            throws说明你有那个可能,倾向。
            throw的话,那就是你把那个倾向变成真实的了。

            两者都是消极处理异常的方式(这里的消极并不是说这种方式不好),只是抛出或者可能抛出异常,但是不会由函数去处理异常,真正的处理异常由函数的上层调用处理。

    五、异常的链化

            在一些大型的,模块化的软件开发中,一旦一个地方发生异常,则如骨牌效应一样,将导致一连串的异常。假设B模块完成自己的逻辑需要调用A模块的方法,如果A模块发生异常,则B也将不能完成而发生异常,但是B在抛出异常时,会将A的异常信息掩盖掉,这将使得异常的根源信息丢失。异常的链化可以将多个模块的异常串联起来,使得异常信息不会丢失。

            异常链化:以一个异常对象为参数构造新的异常对象。新的异对象将包含先前异常的信息。这项技术主要是异常类的一个带Throwable参数的函数来实现的。这个当做参数的异常,我们叫它根源异常(cause)。

            查看Throwable类源码,可以发现里面有一个Throwable字段cause,就是它保存了构造时传递的根源异常参数。这种设计和链表的结点类设计如出一辙,因此形成链也是自然的了。

    public class Throwable implements Serializable {
        private Throwable cause = this;
    
        public Throwable(String message, Throwable cause) {
            fillInStackTrace();
            detailMessage = message;
            this.cause = cause;
        }
    
        public Throwable(Throwable cause) {
            fillInStackTrace();
            detailMessage = (cause == null ? null : cause.toString());
            this.cause = cause;
        }
    
        //........
    }

            下面是一个例子,演示了异常的链化:从命令行输入2个int,将他们相加,输出。输入的数不是int,则导致getInputNumbers异常,从而导致add函数异常,则可以在add函数中抛出一个链化的异常。

    public static void main(String[] args){
        System.out.println("请输入2个加数");
        int result;
        try{
            result = add();
            System.out.println("结果:"+result);
        } catch (Exception e){
            e.printStackTrace();
        }
    }
    //获取输入的2个整数返回
    private static List<Integer> getInputNumbers(){
        List<Integer> nums = new ArrayList<>();
        Scanner scan = new Scanner(System.in);
        try {
            int num1 = scan.nextInt();
            int num2 = scan.nextInt();
            nums.add(new Integer(num1));
            nums.add(new Integer(num2));
        }catch(InputMismatchException immExp){
            throw immExp;
        }finally {
            scan.close();
        }
        return nums;
    }
    
    //执行加法计算
    private static int add() throws Exception{
        int result;
        try {
            List<Integer> nums =getInputNumbers();
            result = nums.get(0)  + nums.get(1);
        }catch(InputMismatchException immExp){
            throw new Exception("计算失败",immExp);  /链化:以一个异常对象为参数构造新的异常对象。
        }
        return  result;
    }
    
    /*
    请输入2个加数
    r 1
    java.lang.Exception: 计算失败
        at practise.ExceptionTest.add(ExceptionTest.java:53)
        at practise.ExceptionTest.main(ExceptionTest.java:18)
    Caused by: java.util.InputMismatchException
        at java.util.Scanner.throwFor(Scanner.java:864)
        at java.util.Scanner.next(Scanner.java:1485)
        at java.util.Scanner.nextInt(Scanner.java:2117)
        at java.util.Scanner.nextInt(Scanner.java:2076)
        at practise.ExceptionTest.getInputNumbers(ExceptionTest.java:30)
        at practise.ExceptionTest.add(ExceptionTest.java:48)
        ... 1 more
    
    */

    六、自定义异常

    自定义异常规则

            如果要自定义异常类,则扩展Exception类即可,因此这样的自定义异常都属于检查异常(checked exception)。如果要自定义非检查异常,则扩展自RuntimeException。

            按照国际惯例,自定义的异常应该总是包含如下的构造函数:
                    一个无参构造函数
                    一个带有String参数的构造函数,并传递给父类的构造函数。
                    一个带有String参数和Throwable参数,并都传递给父类构造函数。
                    一个带有Throwable 参数的构造函数,并传递给父类的构造函数。

    下面是IOException类的完整源代码,可以借鉴。

    public class IOException extends Exception {
        static final long serialVersionUID = 7818375828146090155L;
    
        public IOException() {
            super();
        }
    
        public IOException(String message) {
            super(message);
        }
    
        public IOException(String message, Throwable cause) {
            super(message, cause);
        }
    
        public IOException(Throwable cause) {
            super(cause);
        }
    }

    自定义异常构建

    首先写一个自定义异常,继承Exception,代码如下:

    public class MyException extends Exception {
    
        public MyException() {
            super();
        }
    
        public MyException(String message) {
            super(message);
        }
    
        public MyException(String message, Throwable cause) {
            super(message, cause);
        }
    
    
        public MyException(Throwable cause) {
            super(cause);
        }
    }

    使用自定义异常

            如果自定义异常是为了提示,在使用的时候,一定要用try..catch,不要直接用throw往外抛。

    public class Test {
        public static void main(String[] args) {
            A a = new A();
            try {
                a.show(-2);
            } catch (MyException e) {
                System.out.println(e.getMessage());
            }
        }
    }
    
    class A {
        public void show(int num) throws MyException {
            if (num < 0) {
                MyException me = new MyException("异常:" + num + "不是正数");
                throw me;//抛出异常,结束方法show()的执行
            }
            System.out.println(num);
        }
    }

    七、异常的注意事项

            1、当子类重写父类的带有 throws声明的函数时,其throws声明的异常必须在父类异常的可控范围内——用于处理父类的throws方法的异常处理器,必须也适用于子类的这个带throws方法 。这是为了支持多态。

            例如,父类方法throws 的是2个异常,子类就不能throws 3个及以上的异常。父类throws IOException,子类就必须throws IOException或者IOException的子类。

            至于为什么?我想,也许下面的例子可以说明。

    class Father {
        public void start() throws IOException {
            throw new IOException();
        }
    }
    
    class Son extends Father {
        public void start() throws Exception {
            throw new SQLException();
        }
    }
    
    /**********************假设上面的代码是允许的(实质是错误的)***********************/
    class Test {
        public static void main(String[] args) {
            Father[] objs = new Father[2];
            objs[0] = new Father();
            objs[1] = new Son();
    
            for (Father obj : objs) {
                // 因为Son类抛出的实质是SQLException,而IOException无法处理它。
                // 那么这里的try。。catch就不能处理Son中的异常。
                // 多态就不能实现了。
                try {
                    obj.start();
                } catch (IOException ioException) {
                    // 处理IOException
                }
            }
        }
    }

            2、Java程序可以是多线程的。每一个线程都是一个独立的执行流,独立的函数调用栈。如果程序只有一个线程,那么没有被任何代码处理的异常会导致程序终止。如果是多线程的,那么没有被任何代码处理的异常仅仅会导致异常所在的线程结束。

            也就是说,Java中的异常是线程独立的,线程的问题应该由线程自己来解决,而不要委托到外部,也不会直接影响到其它线程的执行。

    八、finally块和return

    1、一个不容易理解的事实:在 try块中即便有return,break,continue等改变执行流的语句,finally也会执行。

    public static void main(String[] args){
        int re = bar();
        System.out.println(re);
    }
    private static int bar() {
        try{
            return 5;
        } finally{
            System.out.println("finally");
        }
    }
    /*输出:
    finally
    5
    */

    2、finally中的return 会覆盖 try 或者catch中的返回值。

    public static void main(String[] args){
        int result;
    
        result  =  foo();
        System.out.println(result);     /2
    
        result = bar();
        System.out.println(result);    /2
    }
    
    @SuppressWarnings("finally")
    public static int foo(){
        try{
            int a = 5 / 0;
        } catch (Exception e){
            return 1;
        } finally{
            return 2;
        }
    
    }
    
    @SuppressWarnings("finally")
    public static int bar(){
        try {
            return 1;
        }finally {
            return 2;
        }
    }

    3、finally中的return会抑制(消灭)前面try或者catch块中的异常

    class TestException {
        public static void main(String[] args) {
            int result;
            try {
                result = foo();
                System.out.println(result);           //输出100
            } catch (Exception e) {
                System.out.println(e.getMessage());    //没有捕获到异常
            }
    
    
            try {
                result = bar();
                System.out.println(result);           //输出100
            } catch (Exception e) {
                System.out.println(e.getMessage());    //没有捕获到异常
            }
        }
    
        //catch中的异常被抑制
        @SuppressWarnings("finally")
        public static int foo() throws Exception {
            try {
                int a = 5 / 0;
                return 1;
            } catch (ArithmeticException amExp) {
                throw new Exception("我将被忽略,因为下面的finally中使用了return");
            } finally {
                return 100;
            }
        }
    
        //try中的异常被抑制
        //J2SE 提供的最后一个批注是 @SuppressWarnings。该批注的作用是给编译器一条指令,告诉它对被批注的代码元素内部的某些警告保持静默。
        @SuppressWarnings("finally")
        public static int bar() throws Exception {
            try {
                int a = 5 / 0;
                return 1;
            } finally {
                return 100;
            }
        }
    }

    4、finally中的异常会覆盖(消灭)前面try或者catch中的异常

    public class TestException {
        public static void main(String[] args) {
            int result;
            try {
                result = foo();
            } catch (Exception e) {
                System.out.println(e.getMessage());    //输出:我是finaly中的Exception
            }
    
    
            try {
                result = bar();
            } catch (Exception e) {
                System.out.println(e.getMessage());    //输出:我是finaly中的Exception
            }
        }
    
        //catch中的异常被抑制
        @SuppressWarnings("finally")
        public static int foo() throws Exception {
            try {
                int a = 5 / 0;
                return 1;
            } catch (ArithmeticException amExp) {
                throw new Exception("我将被忽略,因为下面的finally中抛出了新的异常");
            } finally {
                throw new Exception("我是finally中的Exception");
            }
        }
    
        //try中的异常被抑制
        @SuppressWarnings("finally")
        public static int bar() throws Exception {
            try {
                int a = 5 / 0;
                return 1;
            } finally {
                throw new Exception("我是finally中的Exception");
            }
    
        }
    }

    上面的3个例子都异于常人的编码思维,因此我建议:

            不要在fianlly中使用return。

            不要在finally中抛出异常。

            减轻finally的任务,不要在finally中做一些其它的事情,finally块仅仅用来释放资源是最合适的。

            将尽量将所有的return写在函数的最后面,而不是try ... catch ... finally中。

    展开全文
  • Java 八大基本数据类型

    万次阅读 多人点赞 2018-04-27 15:02:51
    1. Java的简单类型及其封装器类Java基本类型共有种,基本类型可以分为三类,字符类型char,布尔类型boolean以及数值类型byte、short、int、long、float、double。数值类型又可以分为整数类型byte、short、int、...
  • 一、java种基本数据类型对应的包装类型:   原始类型 包装类 原始类型所占的字节数  short Short 2个字节  int Integer 4个字节  long Long 8个字节  float Float 4个字节  double Do
  • java杠源码Java-Basic---OOP---问题解决 Java基本问题解决 Java教程 教程 Java 介绍:01 Javajava全息高级编程语言。 Eta 开发了 kore sun 微系统,但目前由 oracle 拥有。 为什么我们应该学习java/特性java...
  • Educoder--Java面向对象(第七章) - Java中的异常

    万次阅读 多人点赞 2020-04-30 15:40:28
    第一题 public class HelloWorld{ public static void main(String[] args){ System.out.print(“HelloWorld...B、编译出错,提示“公有类HelloWorld必须在HelloWorld.java文件中定义” C、运行正常,但没有输出内...
  • Java八大基本数据类型

    万次阅读 多人点赞 2020-12-17 09:58:05
    Java基本数据类型图: 整数类型:byte 1字节,8位,最大存储数据量是255,存放的数据范围是-128~127之间。 构造方法: public Byte(byte value) 构建了一个新分配的Byte表示指定的byte价值。 参数 value -被 ...
  • Java异常

    千次阅读 2019-07-08 13:50:25
    一、异常的概述 二、异常的继承体系和错误的区别 1、异常的继承体系 2、异常与错误的区别 三、异常对象的产生原因和处理方式 1、以数组索引越界异常ArrayIndexOutOfBoundsException为例分析产生原因 2、异常的...
  • Java异常的捕获及处理---小总结

    万次阅读 多人点赞 2017-06-06 15:30:52
    一:异常的基本概念二:异常的基本处理格式三:异常的继承结构四:Java异常处理机制五:throws和throw关键字的作用六:Exception和RunntimeException的区别七:自定义异常:断言的作用和应用1,为什么需要异常...
  • java7新特性(简述八大新特性)

    千次阅读 2018-09-28 10:25:41
    异常处理(捕获多个异常) try-with-resources 增强泛型推断 JSR203 NIO2.0(AIO)新IO的支持 JSR292与InvokeDynamic指令 Path接口、DirectoryStream、Files、WatchService(重要接口更新) fork/join ...
  • Java12的八大新特性

    千次阅读 2019-03-20 16:49:24
    Java12的八大新特性 switch表达式 新形式的开关标签,类似lamada表达式“ case L ->”形式,表示如果标签匹配,则只执行标签右侧的代码,没有break case后的标签支持多个逗号分隔的标签 标签右侧代码支持表达式...
  • 步:jstack -m -l pid (这一步可以提前,如果能发现某些异常线程信息)当然也有很多界面工具查看更清晰一些,我这里用的Jprofiler 从这几步一般能看出问题来了,这是一次排查后的总结,有些步骤可能是多余...
  • Educoder–Java面向对象(第七章+第章)- Java中的异常与文件类【笔记+参考代码】 一、Java中的异常 (一)第一关 1. 在Java中,源文件Test.java中包含如下代码段,则程序编译运行结果是(B) public class ...
  • Java异常处理机制你真的会了吗?完全详解来了

    千次阅读 多人点赞 2020-05-27 20:41:07
    Error通常是灾难性的致命的错误,是程序无法控制和处理的,当出现这些异常时,Java虚拟机(JVM)一般会选择终止线程;Exception通常情况下是可以被程序处理的,并且在程序中应该尽可能的去处理这些异常。 三、异常有...
  • java 异常处理

    千次阅读 2016-05-23 18:43:52
    Java异常是一个描述在代码段中发生的异常(也就是出错)情况的对象。当异常情况发生,一个代表该异常的对象被创建并且在导致该错误的方法中被引发(throw)。该方法可以选择自己处理异常或传递该异常。两种情况下,...
  • Java 基础语法】学会异常处理,祝你国庆快乐

    千次阅读 多人点赞 2021-10-05 04:16:52
    异常的背景1.1 邂逅异常1.2 异常和错误1.3 Java 异常的体系(含体系图)1.4 异常的核心思想1.5 异常的好处2. 异常的基本用法2.1 捕获异常2.1.1 基本语法2.1.2 示例一2.1.3 示例二(含使用调用栈)2.1.4 示例三...
  • Java 里的异常(Exception)详解

    千次阅读 2019-09-20 20:17:38
    为一位初学者, 本屌也没有能力对异常谈得很深入. 只不过Java里关于Exception的东西实在是很多....一, 什么是java里的异常 由于java是c\c++ 发展而来的, 首先我们先看看c语言里的错误. 1.1 c语言里...
  • JAVA 后台全局异常控制

    千次阅读 2016-06-27 15:38:57
    但是我们也不得不看见,利用好异常能使我们快速成长,也能让开发人员快速定位异常,设计好了异常控制,能控制到这个异常是由谁产生的,何时产生的,产生的数据是什么,异常的方法是哪个,异常信息是什么等等,当我们...
  • Java异常总结

    千次阅读 多人点赞 2016-09-06 19:40:54
    java异常的总结,包括java异常处理的关键字,java异常捕获的格式,常见的java异常情况,和java异常处理的原则和技巧
  • 实验六 异常处理。实验七 图形用户界面设计。实验 多线程机制该窗口模拟Windows的计算器功能,添加一个文本行和4个按钮,单击【1】、【2】、【+】按钮时,将按钮的标签添加到文本行中;单击【C】按钮时,清空文本...
  • 史上最全Java初中级面试题,发现网上很多Java初级面试题都没有答案,所以花了很长时间搜集整理出来了这套Java面试题大全,希望对大家有帮助哈~ 本人发现网上虽然有不少Java相关的面试题,但第一未必全,第二未必有...
  • 基础篇从java语言的特点入手,介绍了语法结构、面向对象程序设计基础知识到面向对象程序设计、图形用户界面设计、异常处理、applet和多媒体、二进制i/o、递归等内容。《Java语言程序设计:基础篇(原书第8版)》可作为...
  • 八大排序算法Java

    万次阅读 多人点赞 2016-07-06 17:57:40
    我们这里说说八大排序就是内部排序。    当n较大,则应采用时间复杂度为O(nlog2n)的排序方法:快速排序、堆排序或归并排序序。  快速排序:是目前基于比较的内部排序中被认为是最好的方法,
  • SpringBoot全局异常+JSR303校验解放if判断,更加专注于业务逻辑
  • Java异常真的看这一篇就够了

    千次阅读 多人点赞 2020-10-07 20:27:08
    前言:本篇博客结合培训班视频编写,希望以最通俗易懂的文字,讲明白异常机制。部分在介绍概念的时候,我都会用自问自答的方式来描述,原因是这样子...2)java提供异常机制有什么用? 当程序执行过程中出现了不正常情
  • Java异常的捕获与处理

    万次阅读 2017-05-02 16:21:34
    一、异常是什么? 异常的定义:异常是导致一个程序终端的指令流,一旦出现之后程序就立即退出。 例如:除数为0 int a = 10; int b = 0; System.out.println(a + "/" + b + "=" + a/b); System.out.println(...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 86,628
精华内容 34,651
关键字:

java八大异常

java 订阅