zoukankan      html  css  js  c++  java
  • 【JAVA】 03-Java中的异常和包的使用

    链接:

    目录:

    <>


    • <>

    内容待整理:

    异常

    异常和错误的发生和区别

    • 异常:java运行期间发生的问题就是异常。

    • 错误:

      • java中运行时发生的除了异常Exception还有错误error
      • 异常:通常发生可以有针对性的处理方式的
      • 错误:通常发生后不会有针对性的处理方式
        • error的发生往往都是系统级别的问题,都是jvm所在系统发生的并反馈给jvm的,无法针对处理,只能修正代码。

    异常发生的过程

    • 示例:对给定数组,通过给定的角标获取元素。当角标越界时,异常发生的过程:

    • 两个报错位置:

      • 一个类中的主函数调用语句 int num = getElement(arr, 4);
      • 另一个类中的被调用语句 int element = arr[index];
    • 具体发生过程:

      • 被调用函数中:

        没有找到4的角标,运行时发生了问题,这个问题JVM认识
        这个问题java本身有描述,描述内容有: 问题的名称,问题的内容,问题的发生位置
        既然有这么多信息,java就将这些信息直接封装到对象中:对象名 -- ArrayIndexOutOfBoundsException
        throw new ArrayIndexOutOfBoundsException(index);//问题对象。函数到这里就结束了。
        jvm将问题抛给调用者main。
      • 主函数中:

        主函数就收到了越界异常对象。没有处理
        main函数就会继续抛出调用者jvm
        jvm收到问题后,就做出了最终的处理方式。
        将问题对象中的名称、信息、问题的位置,都显示在屏幕上,让软件使用者知道。
        同时,让程序提前终止。
      • tips -- 两个调用者:

        • 函数的调用者:main函数
        • main函数的调用者:JVM

    异常的简单应用

    • 考虑异常的必要性:

      • 在编写程序时,必须要考虑程序的问题情况。
      • 举例:卖水果功能需要传递钱参数,有可能有假币。
      • 所以定义程序需要考虑程序的健壮性。
      • 处理:加入一些逻辑性的判断。
    • 注:编译--检查语法错误,运行--传值等,故是在运行时报异常

    • 角标越界和空指针异常的自定义

      • 主函数调用:int num = d.detElement(arr, 3)

        • 当arr=null,空指针异常;当索引实参小于0或大于等于arr长度,角标越界异常。
      • 几种非异常抛出的处理的不合理之处:

        • 若仅打印提示语句,则下面的语句仍执行,不可。这一步已经错了,应该停止程序
        • 若return -1,return表示程序正常结束,不可。这一步已经错了,无法继续执行,必定不能正常结束。
      • 逻辑判断+异常抛出格式:

        if(....){ new throw XxxXxx("..."); }
      • 空指针异常示例:

        throw new NullPointerException("arr指向的数组不存在");
      • 数组角标越界异常示例:

        throw new ArrayIndexOutOfBoundsException("错误的角标, "+index+"索引在数组中不存在");
    • 无效参数异常

      • 定义Person对象、构造函数初始化时判断年龄值age是否符合规范

      • 逻辑判断+异常抛出

        if(age<0 || age>200){ new throw IllegalArgumentException(age+",年龄数值异常"); }
      • 注:新学一个异常,通过查阅API文档中“空指针异常”的父类的子类找到

      • 注:发现大部分异常都可以传String类型的参数来辅助说明

    异常的自定义&体系&问题解决

    • 在自定义异常的过程中遇到问题、解决问题的历程和经验

      • 自定义class NoAgeException -- 报错:不兼容 -- 引出Throwable
      • Throwable首字母大写,猜测是类或接口 -- 查阅API文档 -- Throwable是异常和错误的超类
      • Throwable说明:自定义异常被抛出,必须继承Throwable或其子类 -- Throwable有两个子类:Error和Exception
      • 选择性地继承Exception:class NoAgeException extends Exception -- 报错:未报告的异常错误,必须对其进行捕获或声明
      • 对照之前的几个java定义好的异常,查阅其API文档:这几个异常的父类都是RuntimeException
      • 查阅RuntimeException的API文档:RuntimeException执行时,异常以及其子类都无需进行声明 -- 对应错误提示“声明”二字
      • 自定义异常类改为继承RuntimeException:class NoAgeException extends RuntimeException -- 可以抛出,但没有显示实参信息
      • 查阅java定义好的异常的源码:发现其构造函数中带String参数的都继承了父类 super(s); -- 加入super(s)后可以正确抛出并显示提示信息了
    • 问题解决tips:

      • 分析错误提示,提取关键词
      • 查阅API文档并阅读
      • 查阅源码并分析、仿写
    • 自定义异常类最终版:

      class NoAgeException extends RuntimeException{ NoAgeException(){ super(); } NoAgeException(s){ super(s); } }

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

    • 异常分为两种:编译时异常和运行时异常

      • 编译时异常:编译器会检测的异常。(语法范围,必须捕获或声明)

      • 运行时异常:编译器不会检测的异常。不需要声明。

        • 如果声明了,就需要调用者给出处理方式。
    • 列举几种常见的运行时异常:

      • IllegalArgumentException
      • NullPointerException
      • IndexOutOfBoundsException
      • ClassCastException
    • Exception需要声明而RuntimeException不需要捕获或声明:

      • 不是功能本身发生的异常,而是因为比如调用者传递参数错误而导致功能运行失败,则不需要声明。
      • 这时也是问题,需要通过异常来体现,但是这个异常不需要声明出来。
      • 声明的目的是为了让调用者进行处理。
      • 不声明的目的是不让调用者进行处理,就是为了让程序停止,让调用者看到现象,并进行代码的修正。
        • 对于“代码修正”,Error同样是代码修正,但是Error是系统底层抛出的,一般是严重错误;而运行时异常是合理范围之内,和底层没有关系。

    声明和捕获

    • 声明

      • 将问题标识出来,报告给调用者。
      • 如果函数内通过throw抛出了编译时异常,而没有捕获,那么必须通过throws进行声明(表示这个方法有可能有问题),让调用者去处理。
      • 格式:类名后不加空格直接跟throws+异常类
      • 示例:
        void show(int x)throws Exception
        Person(String name, int age)throws NoAgeException
      • 注:调用者(如主函数)选择捕获处理时不需要在调用者(如main后)加声明,而抛异常的函数仍需要throws声明,否则报错。
    • 捕获

      • java中对异常有针对性的语句
      • 语句:
        try{ //需要被检测的语句。}
        catch(异常类 变量) //参数 { //异常的处理语句。}
        finally{ //一定会被执行的语句。 }
      • 注1:其中catch语句的参数“异常类”为声明中throws后面跟的异常类
      • 注2:其中finally语句块可以省略
      • 注3:python中的类似语句块: try.. except.. else... (else可省略)
    • tips:

      • 编译器先检查语法等问题,最后才检查异常问题,故当看到编译失败显示的是异常错误,那么恭喜,说明其他的都没问题了。
    • 示例思考:构造函数到底抛出NoAgeException继承Exception呢?还是RuntimeException呢?

      • 继承Exception,则:

        • 必须要throws声明,一声明就告知调用者进行捕获,一旦问题处理了调用者的程序会继续执行
        • 但是如果后面使用到了Person对象的数据,会导致全都失败
      • 继承RuntimeException,则:

        • 不需要throws声明的,这时调用是不可能编写捕获代码的,因为调用根本就不知道有问题
        • 一旦发生NoAgeException,调用者程序会停掉,并由jvm将信息显示到屏幕上,让调用者看到问题,并修正代码

    运行时异常的应用

    • 预判需要编译时异常还是运行时异常

      • 案例1:长方形长和宽的数值异常 -- 运行时异常,仅声明
      • 案例2:毕老师讲课时电脑蓝屏,重启处理 -- 编译时异常,捕获
      • 调用到了声明异常的方法,到底是捕获还是声明?
        • 有具体的捕获处理方法吗?有,捕获;没有,声明。
        • 可以处理,重启就可以了,重启是电脑的功能。

    异常的转换

    • 案例2:当多个异常,且存在不能处理的异常时:异常的转换

    • 一个方法可以通过throws声明多个问题

      public void run()throws LanPingException, MaoYanException
    • 对于声明多个异常的方法,在处理时,需要定义多个catch与之对应

    • 注意<面试多见>:可以一个try多个catch,存在子父类异常时,子类上,父类下

      • 因为catch是顺序执行的,父类上则子类执行不到了
    • 区分能处理异常和能处理因此异常导致的异常

      • 不能处理“冒烟”,但是可以处理冒烟导致的“课程停止”异常
      • 在冒烟中抛“课时停止”,并在主函数中catch“课程停止”异常并进行处理(“换老师”)
      • 不要抛对方不能处理的异常:存钱时,不要跟储户说金库门坏了,说对他的钱的处理方式。

    throw和throws的区别:

    • 1、throw用在函数内
      throws用在函数上
    • 2、throw抛出的是异常对象
      throws用于进行异常类的声明,后面异常类可以有多个,用逗号隔开

    finally的使用

    • 作用:存放一定会执行到的语句

      • 当catch中有return时,在return之前,会先执行完finally中的语句,再return
    • 只有一种情况发生时,finally也不执行(需要把上面的return注释掉)

      • System.exit(0);//退出JVM

    finally的应用场景

    • 只要程序中使用到了具体的资源(数据库连接,IO资源,网络连接socket等)
      需要释放,都必须定义在finally中。(只有在这儿才能真正被释放)
    • 在定义程序时,只要问题发生与否,指定程序都需要执行时,就定义在finally中
    • 注意:面试会考的tips:

      • finally代码块仅在catch的return之前执行,即return前的语句都执行完成后再执行finally。
      • finally代码块中如果有return,则提前结束功能,catch中的return就执行不到了。
      • 能结束函数的语句,除了return,还有异常。抛异常也可以结束。

    try catch finally组合方式

    • 1、try catch:

      • 对代码进行异常检测,并对检测的异常传递给catch处理,叫做:异常捕获处理。
        (注:有catch才叫捕获处理,没catch写try也没用)
        void show()throws?
        //声明不声明需要看捕获的异常是否有处理方式
        //如果有,不声明;如果没有,要抛出的那种,就要声明。
    • 2、try finally:

      • 对代码进行异常检测,检测到异常后,因为没有catch,所以一样会被默认jvm抛出, 叫做:异常没有捕获处理。
      • 但是功能所开启的资源需要进行关闭,所以有finally。
        void show()throws//没有catch,没有捕获处理,要声明
    • 3、try catch finally:

      • 检测异常,并传递给catch处理,并定义资源释放(最常见的)
    • 4、try catch1 catch2 catch3...

      • catch取决于抛多少个异常,针对性处理

    异常在覆盖中的细节

    异常在继承或实现中的使用细节:重点掌握

    • 1、子类在覆盖父类方法时,如果父类的方法声明异常,子类只能声明父类异常,或者该异常的子类,或者不声明。
    • 2、当父类方法声明多个异常时,子类覆盖时,只能声明多个异常的子集。
    • 3、当被覆盖的方法没有异常声明时,子类覆盖时是无法声明异常的。(但是子RuntimeExceptio可以,因为这个不需要声明)
      • 举例:父类存在这种情况,接口也有这种情况(接口没有方法体,所有一般不明确异常)
      • 问题:接口中没有声明异常,而实现的子类覆盖方法时发生了异常,这时怎么办?
        - 无法进行throws声明,只能进行catch的捕获。万一问题处理不了呢?catch中继续throws抛出,但是只能将异常转换成RuntimeException

    package的使用

    • 对于多个类,为了便于管理(类的同名情况),所以java提供了一个解决方案
    • 包机制:落实到操作系统上,就是文件夹。
      对Java的文件进行分文件夹管理。
    • 包的定义:使用关键字 package。

    • 包的作用:

      • 1、对类文件进行管理。
      • 2、给类文件提供了名称空间。
        package mypack;//包名中的所有的字母都小写
        package mypack.haha.hehe.xixi;//多级包时,加句点

    包与包之间的访问

    • 总结:

      • "找不到符号DemoA":类名写错,有了包的类,类名:包名.类名 -- 这才是类的全名称
      • "程序包packa不存在":包在当前目录下没有找到,set classpath=d.myclass
      • 包与包之间的类在访问时,被访问的类以及成员都必须public修饰
    • 注意事项:

      • 被public修饰的类或者接口所属的java文件名必须和类或接口的名称一致。否则编译失败。

    包与包之间的继承

    • 父类可以给其他包中的子类提供一种特殊的权限protected
      只有继承为子类后,才可以访问的权限。
    • 包与包之间访问,只有两种权限可用,public protected(该权限只能给不同包中的子类使用)
    • 保护权限开发用的不多,必须先继承才能用。包与包之间用不了,本包可以。

    import关键字

    • import -- 导入

    • import作用:

      • 包的出现,导致类的名称过长,书写不方便
      • import作用简化类名书写,省略包名。
      • 注:import不是必须要写。不写import,则直接写全包名即可。
    • 一般一个程序中:仅写一个package并且放在程序首行,但是可以写多个import
    • 一个包中需要的类很多时,写通配符星号即可 import packa.*;
      真正开发时,不建议用星号,有几十个就写几十个(高级编辑器一个快捷键解决)
    • 特殊情况一:包中包,多级包时

      • 若只import第一层包名,则包中包下的类文件不可用
      • 明确了使用的类所属的包,而不会导入包中子包中的类
      • 正确方式:import 包1.包2.包n.*
      • 注意:导包 -- 导入的是包中的类,不是包中的包
    • 特殊情况二:不同包中有相同名称的类。

      • 使用该类时,必须指定包名,否则区分不出来,产生了不确定性

    jar包

    • Jar包:java中的压缩包。

      • 读法:架包,勾包
      • 使用不给力,但是真实开发必须用。
    • 打压缩包:javac -cvf xx.jar xxx

      • c:创建新的归档文件
      • v:创建过程中显示详细信息在屏幕上
      • f:归档文件的名称要明确“xx.jar”
      • 最后生成一个xx.jar压缩包
    • 打压缩包后,java运行:直接将jar导入到classpath路径即可正常使用
      • 设置classpath路径:set classpath=.xx.jar
      • java pack.JarDemo可正常运行

    END

  • 相关阅读:
    前端React 条件渲染
    hbuilder小白干货之快捷键大全
    前端React 元素渲染
    mybatis学习笔记五(映射)
    mybatis学习笔记四(配置文件)
    mybatis学习笔记二(sqlsession与开发dao)
    mybatis学习笔记三(动态sql)
    mybatis学习笔记一(mybatis概述)
    必备idea 插件plugins 提高编码效率
    shell提升篇
  • 原文地址:https://www.cnblogs.com/anliux/p/11141831.html
Copyright © 2011-2022 走看看