异常以类和对象的形式存在 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public class _471_Java 中异常以类和对象的形式存在 { public static void main (String[] args) { NumberFormatException nfe = new NumberFormatException("数字格式化异常" ); System.out.println(nfe); NullPointerException npe = new NullPointerException("空指针异常" ); System.out.println(npe); int t = 10 /0 ; } }
UML以及starUML
java的异常处理机制 异常在java中以类和对象的形式存在。那么异常的继承结构是怎样的?我们可以使用UML图来描述一下继承结构。 画UML图有很多工具,例如:Rational Rose (收费的)、startMz等
什么是UML?有什么用? UML是一种统一建模语言-一种图标式语言(画图的) UML不是只有java中使用。只要是面向对象的编程语言,都有UML 一般画UM图的都是软件架构师或者说是系统分析师。这些级别的人员使用的。软件设计人员使用UML。 在UML图中可以描述类和类之间的关系,程序执行的流程,对象的状态等.
异常的继承结构
object
Object下有Throwable (可抛出的)
Throwable下有两个分支:Error(不可处理,直接退出JvM)和Exception (可处理的)
Exception下有两个分支:
Exception的直接子类:编译时异常(要求程序员在编写程序阶段必须预先对这些异常处理)
RuntimeException:运行时异常。(在编写程序阶段程序员可以预先处理,也可以不管)
编译时异常和运行时异常的区别
编译时异常和运行时异常,都是发生在运行阶段。编译阶段异常是不会发生的。
编译时异常因为什么而得名? 因为编译时异常必须在编译(编写)阶段预先处理,如果不处理编译器报错,因此得名。
所有异常都是在运行阶段发生的。因为只有程序运行阶段才可以new对象。因为异常的发生就是new异常对象。
编译时异常发生概率高,运行时异常概率低。
编译时异常又称为 受检异常 和 受控异常
运行时异常又称为 未受检异常 和 非受控异常
异常的两种处理方式
在方法声明的位置上使用 throws 关键字
使用 try catch 语句对异常捕捉
如果一直上抛,抛到 main,main抛给调用者JVM,JVM只有一种结果,终止java程序执行
上抛类似推卸责任,catch表示拦下,异常真正解决,调用者不知道
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public class _482_ 异常处理的原理 { public static void main (String[] args) throws ClassNotFoundException { doSome(); try { doSome(); }catch (ClassNotFoundException e){ e.printStackTrace(); } } public static void doSome () throws ClassNotFoundException { System.out.println("doSome" ); } }
运行时异常编写程序时可以不处理 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public class _480_ 运行时异常编写程序时可以不处理 { public static void main (String[] args) { System.out.println(100 / 0 ); System.out.println("Hello" ); } }
异常捕捉和上抛的联合使用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;public class _483_ 异常捕捉和上抛的联合使用 { public static void main (String[] args) { m1(); } public static void m1 () { System.out.println("m1 begin" ); try { m2(); } catch (IOException e) { System.out.println("该文件被删除" ); } System.out.println("m1 end" ); } public static void m2 () throws FileNotFoundException, IOException { System.out.println("m2 begin" ); m3(); System.out.println("m2 end" ); } public static void m3 () throws FileNotFoundException { System.out.println("m3 begin" ); new FileInputStream("D:\\Workspace\\使用说明.docx" ); System.out.println("m3 end" ); } }
深入try catch
多个catch的时候,从上到下的catch需要从小到大的Exception
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;public class _485_try_catch 深入 { public static void main (String[] args) { try { FileInputStream fis = new FileInputStream("D:\\xxxxxx" ); fis.read(); } catch (FileNotFoundException e) { System.out.println("文件不存在" ); } catch (IOException e){ System.out.println("read 失败" ); } } }
jdk8新特性
catch中加入 “|” 运算符1 2 3 4 5 6 7 8 9 10 11 12 13 14 import java.io.FileInputStream;import java.io.FileNotFoundException;public class _486_Java8 新特性 { public static void main (String[] args) { try { FileInputStream fis = new FileInputStream("D:\\xxxxx" ); } catch (FileNotFoundException | NullPointerException e) { System.out.println("文件不存在? 空指针异常?" ); } } }
上抛和捕捉怎么选择 如果希望调用者处理,使用throws
异常对象的常用方法 getMessage() 1 2 3 4 5 6 7 8 9 10 11 public class _488_ 异常对象的常用方法 { public static void main (String[] args) { NullPointerException npe = new NullPointerException("空指针异常" ); String msg = npe.getMessage(); System.out.println(msg); System.out.println("======" ); } }
printStackTrace() 1 2 3 4 5 6 7 8 9 10 11 12 13 public class _488_ 异常对象的常用方法 { public static void main (String[] args) { NullPointerException npe = new NullPointerException("空指针异常" ); npe.printStackTrace(); System.out.println("======" ); } }
异常信息如何查看 异常追踪信息从上往下看… SUM公司写的代码就不用看了…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 import java.io.FileInputStream;import java.io.FileNotFoundException;public class _489_ 异常对象的常用方法 { public static void main (String[] args) { try { m1(); } catch (FileNotFoundException e) { e.printStackTrace(); } System.out.println("hello" ); } public static void m1 () throws FileNotFoundException { m2(); } private static void m2 () throws FileNotFoundException { m3(); } private static void m3 () throws FileNotFoundException { new FileInputStream("D:\\xxxxxx" ); } }
finally子句的使用
try中的语句就算发生异常 finally 中的语句可以正常运行
所以finally语句比较有保障,比如close文件
try 可以直接和 finally 连用
try 中就算 return,finally 内的语句也会执行,也就是先执行 try 后执行 finally 最后 return
退出JVM finally语句不执行
java中有一条这样的规则: 方法体中的代码必须遵循自上而下顺序战次逐行执行(亘古不变的语法! )
123 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;public class _490_finally 子句的使用 { public static void main (String[] args) { FileInputStream fis = null ; try { fis = new FileInputStream("D:\\1Devc++ file\\00001.cpp" ); String s = null ; s.toString(); fis.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e){ e.printStackTrace(); } catch (NullPointerException e){ e.printStackTrace(); } finally { try { fis.close(); } catch (IOException e) { e.printStackTrace(); } System.out.println("======" ); } } }
4 1 2 3 4 5 6 7 8 9 10 11 public class _491_finally 子句的使用 { public static void main (String[] args) { try { System.out.println("try..." ); return ; }finally { System.out.println("finally..." ); } } }
5 1 2 3 4 5 6 7 8 9 10 11 public class _492_ 退出JVMfinally 语句不执行 { public static void main (String[] args) { try { System.out.println("try..." ); System.exit(0 ); }finally { System.out.println("finally..." ); } } }
6 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 public class _493_finally 的面试题 { public static void main (String[] args) { System.out.println(f()); } public static int f () { int i = 100 ; try { return i; }finally { ++i; System.out.println("finally!" ); } } }
final_finally_finalize的区别
final 是一个关键字,表示最终的,不变的
finally 也是一个关键字,和try连用,finally语句块中的语句一定执行
finalize 是 Object 中的一个方法,所以是标识符,是JVM的GC的垃圾回收器负责调用
1 2 3 4 5 6 7 8 9 public class _494_final_finally_finalize 的区别 { public static void main (String[] args) { Object o = new Object(); } }
Java中怎么自定义异常
编写一个类继承Exception或者RuntimeException.
提供两个构造方法,一个无参数的,一个带有string参数的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 public class _495_java 中如何自定义异常 { public static void main (String[] args) { MyException1 e1 = new MyException1("用户名不能为空" ); e1.printStackTrace(); } } class MyException1 extends Exception { public MyException1 () { } public MyException1 (String message) { super (message); } } class MyException2 extends RuntimeException { public MyException2 () { } public MyException2 (String message) { super (message); } }
异常在实际开发中的作用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 public class _496_ 异常在实际开发中的作用 { public static void main (String[] args) { MyStack sta = new MyStack(); try { sta.pop(); } catch (MyStackOperatorException e) { e.printStackTrace(); } System.out.println(" =============== " ); try { sta.push(1 ); sta.push(2 ); sta.push(3 ); sta.push(4 ); sta.push(5 ); sta.push(6 ); sta.push(7 ); sta.push(8 ); sta.push(9 ); sta.push(10 ); sta.push(11 ); } catch (MyStackOperatorException e) { e.printStackTrace(); } } } class MyStack { private Object[] elements; private int index; public MyStack () { elements = new Object[10 ]; index = 0 ; } public void push (Object o) throws MyStackOperatorException { if (index >= 10 ){ throw new MyStackOperatorException("栈已满~" ); } elements[index++] = o; System.out.println("push " + o); } public void pop () throws MyStackOperatorException { if (index <= 0 ){ throw new MyStackOperatorException("栈空了~" ); } --index; } public Object[] getElements() { return elements; } public void setElements (Object[] elements) { this .elements = elements; } public int getIndex () { return index; } public void setIndex (int index) { this .index = index; } } class MyStackOperatorException extends Exception { public MyStackOperatorException () { } public MyStackOperatorException (String message) { super (message); } }
异常与方法覆盖 重写之后的方法不能比重写之前更宽泛的编译时的异常,可以更少。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 public class _497_ 异常与方法覆盖 { public static void main (String[] args) { } } class Animal { public void m1 () { } public void m2 () throws Exception { } } class Cat extends Animal { }
异常中的关键字
try
catch
finally
throws 在方法上声明
throw 手动抛出异常
异常作业 编写程序模拟用户注册: 1、程序开始执行时,提示用户输入”用户名”和”密码”信息。 2、输入信息之后,后台java程序模拟用户注册。 3、注册时用户名要求长度在[6-14]之间,小于或者大于都表示异常。 注意: 完成注册的方法放到一个单独的类中-异常类自定义即可-
1 2 3 4 5 class Userservice { public void register (string username ,string password) { } )
编写main方法,在main方法中接收用户输入的信息,在main方法中调用Userservice的register方法完成注册
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 public class _498_ 异常作业 { public static void main (String[] args) { UserServices u = new UserServices(); try { u.register(null ,"123123123" ); } catch (MyRegisterException e) { e.printStackTrace(); } } } class UserServices { public void register (String username, String pasaword) throws MyRegisterException { if (username != null && 6 <= username.length() && username.length() <= 14 ){ System.out.println("登陆成功~~" ); } else { throw new MyRegisterException("用户名长度不对!!!" ); } } } class MyRegisterException extends Exception { public MyRegisterException () { } public MyRegisterException (String message) { super (message); } }
武器数组作业 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 public class _499_ 武器数组作业 { public static void main (String[] args) { Army army = new Army(3 ); try { army.addWeapon(new Tank()); army.addWeapon(new Radar()); army.addWeapon(new Missile()); army.addWeapon(new Tank()); } catch (addWeaponException e) { e.printStackTrace(); } System.out.println("=======" ); army.moveAll(); System.out.println("=======" ); army.attackAll(); } } class Army { Weapon[] w; int index; public Army (int count) { w = new Weapon[count]; index = 0 ; } public void addWeapon (Weapon o) throws addWeaponException { if (index < w.length){ w[index++] = o; System.out.println(o + "加入成功~" ); } else throw new addWeaponException("武器数量已满~" ); } public void moveAll () { for (int i = 0 ; i < w.length; i++) { if (w[i] instanceof Movable){ Movable o = (Movable) w[i]; o.move(); } } } public void attackAll () { for (int i = 0 ; i < w.length; i++) { if (w[i] instanceof Attachable){ Attachable o = (Attachable) w[i]; o.attack(); } } } } class Weapon { @Override public String toString () { return "一个武器" ; } } class Missile extends Weapon implements Attachable { @Override public void attack () { System.out.println("Missile attack~" ); } @Override public String toString () { return "Missile" ; } } class Radar extends Weapon implements Movable { @Override public void move () { System.out.println("Radar move~" ); } @Override public String toString () { return "Radar" ; } } class Tank extends Weapon implements Movable , Attachable { @Override public void move () { System.out.println("tank move~" ); } @Override public void attack () { System.out.println("tank attack~" ); } @Override public String toString () { return "Tank" ; } } interface Movable { void move () ; } interface Attachable { void attack () ; } class addWeaponException extends Exception { public addWeaponException () { } public addWeaponException (String message) { super (message); } }