{"id":21974126,"url":"https://github.com/javaobjects/demo515","last_synced_at":"2026-05-04T19:35:40.030Z","repository":{"id":105562316,"uuid":"195965101","full_name":"javaobjects/demo515","owner":"javaobjects","description":"异常处理","archived":false,"fork":false,"pushed_at":"2019-08-01T06:00:01.000Z","size":311,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-22T23:27:46.776Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/javaobjects.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-07-09T08:21:19.000Z","updated_at":"2019-08-01T06:00:03.000Z","dependencies_parsed_at":null,"dependency_job_id":"5a67a83c-f361-4257-9268-54dc213fcb83","html_url":"https://github.com/javaobjects/demo515","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/javaobjects/demo515","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/javaobjects%2Fdemo515","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/javaobjects%2Fdemo515/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/javaobjects%2Fdemo515/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/javaobjects%2Fdemo515/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/javaobjects","download_url":"https://codeload.github.com/javaobjects/demo515/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/javaobjects%2Fdemo515/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32622225,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-04T10:08:07.713Z","status":"ssl_error","status_checked_at":"2026-05-04T10:08:02.005Z","response_time":58,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-29T15:38:45.153Z","updated_at":"2026-05-04T19:35:39.997Z","avatar_url":"https://github.com/javaobjects.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 111-Java-异常处理机制.md\n\n#### 异常简介\n\n+ 异常的定义\n    + 运行期间出现的错误，而不是编译时的语法错误\n    + 例如，\n        + 打开一个不存在的文件\n        + 网络连接中断\n        + 操作数组越界等\n+ 异常的定义\n    + 示 例 **数组越界异常**\n```\npublic class excption_sample {\n    public static void main(String args[ ]){\n       int i = 0;\n       String greetings[ ] = {\"Hello World\",\n                                       \"Hello Dingdang\",\n                                       \"Hello Kitty\"};\n\n       while(i\u003c4){\n          System.out.println(greetings[i]);\n          i++;\n       }\n    }\n}\n```\n#### 异常类的继承关系\n\n+ 异常的继承树\n\n![](111-Images/1.png)\n\n+ 异常类的体系结构\n\n![](111-Images/2.png)\n\n+ Object 类的直接子类Throwable描述了所有被虚拟机抛出的非正常状况。一般情况下很少用Throwable，而是使用它的两个子类Error、Exception。\n    + Error类特指应用程序在运行期间发生的严重错误。如：虚拟机内存用尽、堆栈溢出等等。一般情况下这种错误都是灾难性的，所以没有必要使用异常处理机制处理Error。\n    + Exception类有几十个子类，描述了不同类型的异常，其中：\n        + 以RuntimeException为代表的一些类，称为非检查性异常（unchecked Exception），\n        + 以IOException为代表的一些类为检查性异常（checked Exception）。所谓的检查和非检查是指编译器在编译时是否检查。如果代码中存在检查性异常，必须进行异常处理，否则编译时不能通过；而非检查性异常编译时不进行检查，到运行时才会显现。\n\n+ 异常类型  \n    + 检查性异常（checked exception）\n        + 若系统运行时可能产生该类异常，则必须写出相应的处理代码，否则无法通过编译\n        + 非RuntimeException异常\n\n    + 非检查性异常（unchecked exception）\n        + 若系统运行时可能产生该类异常，则不必在程序中声明对该类异常的处理，就可以编译执行\n        + RuntimeException：运行时异常\n+ Java为何分别处理这两类异常？\t\n\n一般我们不在 代码中处理非检查性异常，这类异常都在运行时抛出。原因主要是由于程序员经验不足或是思维不缜密造成。如:数组越界异常（ArrayIndexOutOfBoundsException）、整数除以0异常（ArithmeticException）等，这类异常其实就是我们通常说的bug。所以，这类异常应通过反复测试尽量避免，而不应该靠异常处理机制来解决。\n\n检查性异常不同，就算程序员再有经验，也是难以避免。如：用户连接数据库的异常（SQLException），如果是由于数据库服务器没有启动或是网络中断引起的，我们程序员是无法避免的。又如：程序要读取光盘中的文件，而用户忘记插入光盘，此时则抛出文件没找到异常（FileNotFoundException），程序员也无法避免。\n\n综上，异常处理机制主要处理检查性异常而不是非检查性异常和Error。\n\n|非检查性异常|\t说明|\n| -------- | ------ |\n|RuntimeException |\tjava.lang包中多数异常的基类| \n|ArithmeticException |\t算术错误，如除以 0| \n|IllegalArgumentException |\t方法收到非法参数| \n|ArrayIndexOutOfBoundsException| \t数组下标出界 |\n|NullPointerException |\t试图访问 null 对象引用 |\n\n\n|检查性异常\t|说明|\n| -------- | ---- |\n|ClassNotFoundException|\t无法找到想要创建对象的类文件|\n|IOException |\tI/O 异常的根类| \n|FileNotFoundException |\t不能找到文件| \n|EOFException| \t文件结束| \n|IllegalAccessException |\t对类的访问被拒绝| \n|NoSuchMethodException| \t请求的方法不存在 |\n|InterruptedException |\t线程中断| \n\n#### 异常处理机制\n\n+ 异常的处理过程\n\n![](111-Images/3.png)\n\n+ 在Java程序执行过程中如果出现异常事件，系统会发出异常报告，这时系统将生成一个异常类对象，异常类对象封装了异常事件的信息并将其提交给Java运行时系统\n+ Java 中可用于处理异常的两种方式：\n    + 自行处理：可能引发异常的语句封入在 try 块内，而处理异常的相应语句则封入在 catch 块内。\n    + 回避异常：在方法声明中包含 throws 子句，通知潜在调用者，如果发生了异常，必须由调用者处理。\n\n+ try…catch语句 \n\n**示例  Exception_sample_1.java**\n\n```\npublic class excption_sample {\n    public static void main(String args[ ]){\n       int i = 0;\n       String greetings[ ] = {\"Hello World\",\n                            \"Hello Dingdang\",\n                            \"Hello Kitty\"};\n      try{  //try{}表示可能发生异常的语句     \n          while(i\u003c4){\n             System.out.println(greetings[i]);\n             i++;\n          }\n      }catch(ArrayIndexOutOfBoundsException e){//catch( )内的参数异常类对象的声明\n             System.out.println(“数组越界异常”);//catch{}内的语句是对异常的处理\n        }\n      }\n }\n```\n+ catch块，是用来捕获并处理try块抛出的异常的代码块。没有try块，catch块不能单独存在。我们可以有多个catch块，以捕获不同类型的异常\n+ 如果程序抛出多个不同类型的异常，我们需要多个catch()语句来处理。\n+ 和特殊异常类相关联的catch()块必须写在和普通异常类相关联的catch()之前。\n+ try{…}和catch( ){…}之间不可以添加任何代码\n\n![](111-Images/4.png)\n\n+ 每次try块有异常抛出，系统会试着从上到下往每个catch块中传参，直到遇到一个类型匹配的catch块为止。\n+ 如上示例中最后一个catch块中的形参为Exception类型，它是所有异常类的父类，任何异常都可以传参到该块中，该块可以处理任何类型的异常。因此，这个catch块只能放到最后面，否则所有的异常都被它处理了，其他的catch块就不能分门别类的起作用了。\n+ 如果编写过程中我们违背了这一点，会产生编译错误：\t\n```\nexception java.io.ArrayOutOfBoundsException has already bean caught\n```\n+ 一般一个catch块中是专门处理异常的代码，在程序中这里还可以是记录日志的语句，当发生异常时记录该日志，无异常时将不会记录。\n\n\n#### 异常处理机制——Java7特性\n\n+ catch表达式调整\n    + JDK 7中，单个catch块可以处理多个异常类型\n\n```\ntry {  \n   ......  \n   \n} catch(ClassNotFoundException|SQLException ex) {  \n    ex.printStackTrace();  \n   \n} \n```\n+ catch表达式调整\n    + 这种用法是不包括异常的子类型的。比如说，下面这个多个异常的捕获语句就会抛出编译错误：\n```\ntry {   \n   ......  \n  \n} catch (FileNotFoundException | IOException ex) {  \n   ex.printStackTrace();  \n} \n```\n+ finally 语句\n    + finally语句放在try …catch语句后\n    + fianlly语句中的代码块不管异常是否被捕获总是要执行\n![](111-Images/5.png)\n    + 通常在finally语句中可以进行资源的清除操作，如：关闭打开文件、删除临时文件\n    + 对应finally代码中的语句，即使try代码块和catch代码块中使用了return语句退出当前方法或般若break跳出某个循环，相关的finally代码块都有执行。\n    + 当try或catch代码块中执行了System.exit(0)时，finally代码块中的内容不被执行\n\n```\ncatch (ArrayIndexOutOfBoundsException e) {\n   System.out.println(“Out of Bounds!”);\n   return;\n }\ncatch (RuntimeException e) {\n   System.out.println(“Runtime Exception!”);}\ncatch (Exception e) {\n   System.out.println(“Exception!”); \n   }finally{\n       System.out.println(\"program is running into finally!\");//无论是否捕获异常，系统都会执行该语句\n   }\n```\n+ throws关键字\n    + 如果一个方法中的语句执行时可能生成某种异常，但是并不能确定如何处理，则可以在程序所在的函数声明后，使用throws关键字抛出异常\n```\nclass ThrowsDemo{\n    public  void proc( ) throws IOException{\n        System.out.println(\"inside proc\");          \n    }\n}\n```\n+ 位置：函数参数列表的后面\n+ throws关键字后面，可以跟多个异常，中间用逗号分割 \n+ throws关键字抛出的异常，由调用该函数的函数处理。\n+ 方法中如果用throws关键字抛出：\n    + 非检查性异常：上一级去除异常，直到不抛出异常；\n    + 检查性异常\n        + 在调用该函数内try-catch，把异常处理掉。那么不往上一级抛出异常，程序正常执行，上一级方法并不知道曾经产生异常。\n        + 用throws声明方法抛出异常，不进行处理。谁调用谁负责处理\n        + 覆盖方法抛出异常时，可以抛出与被覆盖方法相同的异常或者被覆盖方法异常的子类异常。\n```\npublic class ThrowTest\n{\n\tpublic void createFile(String path) throws IOException{\n\t\tFile f= new File(path);\n\t\tf.createNewFile();\n\t}\n\tpublic static void main(String[] args){\n\t\tThrowTest  tt = new ThrowTest();\n\t\ttry{\n\t\t\ttt.createFile(\"c:/abc.txt\");\n\t\t}catch(IOException ex){\n\t\t\tex.printStackTrace();\n\t\t}\n\t}\n}\n```\n+ throw语句         \n    + 异常是通过关键字 throw 抛出，程序可以用throw语句引发明确的异常。如：\n```\nvoid doA() throws Exception1 {\n    try {\n        .....\n    }catch(Exception1 e){\n        throw e;\n    }catch(Exception2 e){\n        System.out.println(\"出错了\");\n    }\n}\n```\n+ throw语句用在方法体内,表示抛出异常,由方法体内的语句处理。不能单独使用，要么和try.. catch…一起使用，要么和throws一起使用。\n+ throw语句的操作数一定是Throwable类类型或Throwable子类类型的一个对象\n```\npublic class ThrowTest\n{\n\tpublic void createFile(String path) throws IOException{\n\t\tFile f= new File(path);\n\t\ttry{\n\t\t\tf.createNewFile();\n\t\t}catch(IOException ie){\n\t\t\tie.printStackTrace();\n\t\t\tthrow ie;    //再次抛出\n\t\t}\n\t}\n\tpublic static void main(String[] args){\n\t\tThrowTest  tt = new ThrowTest();\n\t\ttry{\n\t\t\ttt.createFile(\"c:/abc.txt\");\n\t\t}catch(IOException ex){\n\t\t\tex.printStackTrace();\n\t\t}\n\t}\n}\n```\n**示例代码：**\n\n```\npackage 异常的处理;\n\npublic class TestExceptionHandler {\n\t\n\tpublic int sum(int a,int b) {\n\t\treturn a + b;\n\t}\n\t\n\tpublic static void main(String[] args) throws ClassNotFoundException {//2.消积处理\n\n\t\t//模拟异常，看怎么处理？\n\t\t\n\t\t//2.消积处理：异常抛出虚拟机，程序终止\n\t\tClass.forName(\"java.a.Date\");\n\t\t\n\t\t//1.积极处理:程序继续执行完毕\n//\t\ttry {\n//\t\t\tClass.forName(\"java.a.Date\");\n//\t\t} catch (Exception e) {\n//\t\t\te.printStackTrace();\n//\t\t}\n//\t\tfor (int i = 0; i \u003c 100; i++) {\n//\t\t\tSystem.out.println(i);\n//\t\t}\n\n\t}\n\n}\n```\n\n```\npackage 异常的处理;\n\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileNotFoundException;\nimport java.io.IOException;\n\npublic class TestExceptionHandler2 {\n\t\n\tpublic static void main(String[] args){\n\n\t\tFile file = new File(\"e:\\\\HelloWorld.java\");\n\t\t\n\t\t\n\t\tFileInputStream is = null;\n\t\ttry {\n\t\t\tis = new FileInputStream(file);\n\t\t\tint result = is.read();//根据提示选择clause to surrounding by \n\t\t\t\n\t\t\t\n\t\t\tClass.forName(\"java.a.b\");\n//\t\t} catch (ClassNotFoundException | IOException e) {//Java7对catch的改写，可以多个异常同时写\n//\t\t\te.printStackTrace();\n\t\t} catch (FileNotFoundException e) {\n\t\t\tSystem.out.println(\"a\");\n\t\t\te.printStackTrace();\n\t\t} catch (ClassNotFoundException e1) {\n\n\t\t\te1.printStackTrace();\n\t\t} catch (IOException e) {\n\t\t\tSystem.out.println(\"b\");\n\t\t\te.printStackTrace();\n//1.finally语句块有什么 作用？\n//\t用于释放资源，即使代码抛出异常，\n//\tfinally语句块中的代码也会执行\n\t\t}finally {\n\t\t\ttry {\n\t\t\t\tis.close();\n\t\t\t} catch (IOException e) {\n\t\t\t\te.printStackTrace();\n\t\t\t}\n\t\t}\n//2.final finalize finally 有什么区别？\n/**\n * final 修饰的类不能有子类 \n *       修饰的方法不能重写 \n *       修饰的变量不能重新赋值，叫常量\n * finalize：如果发现有垃圾对象的话就会调用finalize()方法，释放它所占用的内存 \n * finally: 确保我们程序当中有些释放资源的方法能够执行，\n * \t\t\t一般跟在try catch语句块后面     \t\n */\n\n\t}\n\n}\n```\n\n```\npackage 异常的处理;\n\nimport java.io.File;\nimport java.io.FileInputStream;\n\n\npublic class TestRuntimeException {\n\n\tpublic static void main(String[] args) throws Exception {//消积处理\n//\t\tString a = null;\n//\t\tSystem.out.println(a.length());//java.lang.NullPointerException\n\t\t\n\t\tFile file = new File(\"e:\\\\HelloWorld.java\");\n\t\t\n\t\t\n//\t\ttry {\n//\t\t\tFileInputStream is = new FileInputStream(file);\n//\t\t\t\n//\t\t\tint result = is.read();\n//\t\t} catch (Exception e) {\n//\t\t\te.printStackTrace();\n//\t\t}//积极处理\n\t\t\n\t\tFileInputStream is = new FileInputStream(file);\n\t\t\n\t\tint result = is.read();\n\t}\n}\n```\n```\npackage 异常的处理;\n\npublic class Test {\n\n\tpublic static void main(String[] args) {\n\t\t\n//\t\tdouble p = \"\";//这是语法错误，称不上异常\n\t\t/**\n\t\t * 异常：\n\t\t * 代码运行期间出现的错误\n\t\t * 打开一个不存在的文件\n\t\t * 网络连接中断\n\t\t * 操作数组越界等\n\t\t */\n\t\t\n\t\tfor (int i = 0; i \u003c 10; i++) {\n\t\t\tSystem.out.println(i);\n\t\t}\n\t\t\n//\t\tint b = 0;\n//\t\tif(b != 0) {\n//\t\t\tint a = 10 / b;\n//\t\t}\n\t\t\n\t\ttry {\n\t\t\tClass.forName(\"java.a.b\");\n\t\t\tSystem.out.println(\"a\");\n\t\t} catch (Exception e) {\n\t\t\tSystem.out.println(\"b\");\n\t\t\te.printStackTrace();\n\t\t}finally {\n\t\t\tSystem.out.println(\"d\");\n\t\t}\n\t\t\n\t\tSystem.out.println(\"c\");\n\t\t\n\t\t\n\t\t\n\t\tfor (int i = 0; i \u003c 10; i++) {\n\t\t\tSystem.out.println(\"i: \" + i);\n\t\t}\n\t}\n}\n```\n\n**以就就是我关于 *Java-自定义异常类*  知识点的整理与总结的全部内容，[另附源码](https://github.com/javaobjects/demo515)**\n\n==================================================================\n#### 分割线\n==================================================================\n\n**博主为咯学编程：父母不同意学编程，现已断绝关系;恋人不同意学编程，现已分手;亲戚不同意学编程，现已断绝来往;老板不同意学编程,现已失业三十年。。。。。。如果此博文有帮到你欢迎打赏，金额不限。。。**\n\n![](111-Images/pay.png)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjavaobjects%2Fdemo515","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjavaobjects%2Fdemo515","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjavaobjects%2Fdemo515/lists"}