关于JAVA异常(Exception)的学习
0、异常处理机制
0.1、java中异常的作用是:增强程序健壮性。
0.2、java中异常以类和对象的形式存在。
1、java的异常处理机制
1.1、异常在java中以类和对象的形式存在。那么异常的继承结构是怎样的?
我们可以使用UML图来描述一下继承结构。
画UML图有很多工具,例如:Rational Rose(收费的)、starUML等....
Object
Object下有Throwable(可抛出的)
Throwable下有两个分支:Error(不可处理,直接退出JVM)和Exception(可处理的)
Exception下有两个分支:
Exception的直接子类:编译时异常(要求程序员在编写程序阶段必须预先对这些异常进行处理,如果不处理编译器报错,因此得名编译时异常。)。
RuntimeException:运行时异常。(在编写程序阶段程序员可以预先处理,也可以不管,都行。)
1.2、编译时异常和运行时异常,都是发生在运行阶段。编译阶段异常是不会发生的。
编译时异常因为什么而得名?
因为编译时异常必须在编译(编写)阶段预先处理,如果不处理编译器报错,因此得名。
所有异常都是在运行阶段发生的。因为只有程序运行阶段才可以new对象。
因为异常的发生就是new异常对象。
1.3、编译时异常和运行时异常的区别?
编译时异常一般发生的概率比较高。
举个例子:
你看到外面下雨了,倾盆大雨的。
你出门之前会预料到:如果不打伞,我可能会生病(生病是一种异常)。
而且这个异常发生的概率很高,所以我们出门之前要拿一把伞。
“拿一把伞”就是对“生病异常”发生之前的一种处理方式。
对于一些发生概率较高的异常,需要在运行之前对其进行预处理。
运行时异常一般发生的概率比较低。
举个例子:
小明走在大街上,可能会被天上的飞机轮子砸到。
被飞机轮子砸到也算一种异常。
但是这种异常发生概率较低。
在出门之前你没必要提前对这种发生概率较低的异常进行预处理。
如果你预处理这种异常,你将活的很累。
假设你在出门之前,你把能够发生的异常都预先处理,你这个人会更加
的安全,但是你这个人活的很累。
假设java中没有对异常进行划分,没有分为:编译时异常和运行时异常,
所有的异常都需要在编写程序阶段对其进行预处理,将是怎样的效果呢?
首先,如果这样的话,程序肯定是绝对的安全的。
但是程序员编写程序太累,代码到处都是处理异常
的代码。
1.4、编译时异常还有其他名字:
受检异常:CheckedException
受控异常
1.5、运行时异常还有其它名字:
未受检异常:UnCheckedException
非受控异常
1.6、再次强调:所有异常都是发生在运行阶段的。
1.7、Java语言中对异常的处理包括两种方式:
第一种方式:在方法声明的位置上,使用throws关键字,抛给上一级。
谁调用我,我就抛给谁。抛给上一级。
第二种方式:使用try..catch语句进行异常的捕捉。
这件事发生了,谁也不知道,因为我给抓住了。
举个例子:
我是某集团的一个销售员,因为我的失误,导致公司损失了1000元,
“损失1000元”这可以看做是一个异常发生了。我有两种处理方式,
第一种方式:我把这件事告诉我的领导【异常上抛】
第二种方式:我自己掏腰包把这个钱补上。【异常的捕捉】
张三 --> 李四 ---> 王五 --> CEO
思考:
异常发生之后,如果我选择了上抛,抛给了我的调用者,调用者需要
对这个异常继续处理,那么调用者处理这个异常同样有两种处理方式。
1.8、注意:Java中异常发生之后如果一直上抛,最终抛给了main方法,main方法继续
向上抛,抛给了调用者JVM,JVM知道这个异常发生,只有一个结果。终止java程序的执行。
1 package exception; 2 3 /* 4 * 什么是异常?异常处理机制有什么用 5 */ 6 public class ExceptionTest01 { 7 /** 8 * 异常对象有两个重要的方法 9 * 获取异常简单的描述信息: String msg=exception.getMessage(); 10 * 打印 异常追踪的堆栈信息: exception.printStackTrace(); 11 * 12 */ 13 public static void main(String[] args) { 14 NullPointerException e = new NullPointerException("空指针异常"); 15 String msg = e.getMessage(); 16 System.out.println(msg); 17 //打印异常堆栈信息 18 e.printStackTrace(); 19 System.out.println("hello world"); 20 } 21 22 }
1 package exception; 2 3 import java.io.FileInputStream; 4 import java.io.FileNotFoundException; 5 import java.io.IOException; 6 7 /* 8 * 什么是异常?异常处理机制有什么用 9 */ 10 public class ExceptionTest02 { 11 /** 12 * 13 try catch 子类finally 通常在其对语句块中完成的资源进行释放,关闭 14 finally中的语句肯定会执行 15 * 16 * 17 */ 18 public static void main(String[] args) throws IOException { 19 FileInputStream fis=null; 20 try { 21 //创建输入 22 fis=new FileInputStream("D:\迅雷下载\照片\日职.jpg"); 23 String s=null; 24 //s.toString(); 25 System.out.println("你好"); 26 } catch (FileNotFoundException e) { 27 28 e.printStackTrace(); 29 }finally{ 30 //关闭输入流,为避免程序如果发生异常导致输入流不关闭,建议在finally里关闭输入流 31 if(fis!=null){ 32 fis.close(); 33 System.out.println("try执行了"); 34 //System.exit(0); //退出java虚拟机,后面不执行 35 } 36 } 37 38 System.out.println("try ... finally联合使用"); 39 40 try{ 41 System.out.println("先执行"); 42 43 return;//最后执行 44 45 }finally{ 46 System.out.println("finally 第二次执行,一定会执行"); 47 48 } 49 50 51 //System.out.println("return了,这里不会执行"); 52 } 53 54 }
finally的使用
1 package exception; 2 3 import java.io.FileInputStream; 4 import java.io.FileNotFoundException; 5 import java.io.IOException; 6 7 /* 8 * 什么是异常?异常处理机制有什么用 9 */ 10 public class ExceptionTest02 { 11 /** 12 * 13 try catch 子类finally 通常在其对语句块中完成的资源进行释放,关闭 14 finally中的语句肯定会执行 15 * 16 * 17 */ 18 public static void main(String[] args) throws IOException { 19 FileInputStream fis=null; 20 try { 21 //创建输入 22 fis=new FileInputStream("D:\迅雷下载\照片\日职.jpg"); 23 String s=null; 24 //s.toString(); 25 System.out.println("你好"); 26 } catch (FileNotFoundException e) { 27 28 e.printStackTrace(); 29 }finally{ 30 //关闭输入流,为避免程序如果发生异常导致输入流不关闭,建议在finally里关闭输入流 31 if(fis!=null){ 32 fis.close(); 33 System.out.println("try执行了"); 34 //System.exit(0); //退出java虚拟机,后面不执行 35 } 36 } 37 38 System.out.println("try ... finally联合使用"); 39 40 try{ 41 System.out.println("先执行"); 42 43 return;//最后执行 44 45 }finally{ 46 System.out.println("finally 第二次执行,一定会执行"); 47 48 } 49 50 51 //System.out.println("return了,这里不会执行"); 52 } 53 54 }
面试题:
1 package exception; 2 /** 3 * 面试题 java亘古不变的语法 4 * 1.方法体中的代码必须遵循自上而下的顺序依次执行 5 * 2.return语句一旦执行,整个方法必须结束,return 最后执行 6 * @author ASUS 7 * 8 */ 9 public class ExceptionTest03 { 10 11 public static void main(String[] args) { 12 int s=m(); 13 System.out.println(s); //结果为100 14 } 15 16 private static int m() { 17 int i=100; 18 try{ 19 return i; 20 }finally{ 21 i++; 22 } 23 } 24 25 }
自定义异常:
/*
* 异常的自定义
* 两步:
* 1.写一个类继承exception或者RunctimeException
* 2.提供两个构造方法,一个无参,一个有参
*/
1 package exception; 2 /** 3 * 自定义异常 4 * 5 * @author ASUS 6 * 7 */ 8 public class IllegalNameException extends Exception{ 9 10 public IllegalNameException() { 11 } 12 public IllegalNameException(String s){ 13 super(s); 14 } 15 }
1 package exception; 2 /** 3 * 用户业务类,处理用户相关的业务:例如登录,注册等功能 4 * @author ASUS 5 * 6 */ 7 public class UserService { 8 public void register(String username ,String password) throws IllegalNameException{ 9 10 if(username==null||username.length()<=4||username.length()>=12){ 11 throw new IllegalNameException("用户名错误,长度必须在6-12之间"); 12 13 } 14 System.out.println("注册成功,欢迎"+username); 15 } 16 17 }
package exception; import java.util.Scanner; /** * 用户注册测试类 * @author ASUS * */ public class RegistTest { public static void main(String[] args) { UserService u=new UserService(); Scanner sc=new Scanner(System.in); System.out.println("欢迎来到注册界面!!"); System.out.println("请输入用户名:"); String a = sc.next(); System.out.println("请输入密码:"); String b = sc.next(); try { u.register(a, b); } catch (IllegalNameException e) { System.out.println(e.getMessage()); } } }
2、什么是UML?有什么用?
UML是一种统一建模语言。
一种图标式语言(画图的)
UML不是只有java中使用。只要是面向对象的编程语言,都有UML。
一般画UML图的都是软件架构师或者说是系统分析师。这些级别的人员使用的。
软件设计人员使用UML。
在UML图中可以描述类和类之间的关系,程序执行的流程,对象的状态等.
盖大楼和软件开发一样,一个道理。
盖楼之前,会先由建筑师画图纸。图纸上一个一个符号都是标准符号。
这个图纸画完,只要是搞建筑的都能看懂,因为这个图纸上标注的这些
符号都是一种“标准的语言”。
在java软件开发当中,软件分析师/设计师负责设计类,java软件开发人员
必须要能看懂。