程序执行时,出现了不可预见的错误信息,被称为异常
java将该异常输出到控制台上,供程序员参考,进行程序的修改,使得程序更加健壮
异常在java中以类形式存在,每一个异常类都可以创建异常对象 ——例题一
异常的继承结构:使用UML图描述
Exception是 Throwable(可抛出的)的子类
java语言对异常的处理包括两种方式 ——例题三
异常的重要方法: ——例题六
关于try catch中的finally子句 ——见例七
子类继承父类,继续方法的重写,重写之后的方法不能比重写之前的方法抛出更多(更宽泛)的异常,可以更少。
package Advance.exception; /** * @author 衣鱼 * java提供异常机制的作用 * 程序执行时,出现了不可预见的错误信息,被称为异常 * java将该异常输出到控制台上,供程序员参考,进行程序的修改,使得程序更加健壮 * * 异常在java中以类形式存在,每一个异常类都可以创建异常对象 */ public class EXceptionTest01 { public static void main(String[] args) { //通过异常类,实例化异常对象 NumberFormatException nfe = new NumberFormatException("数字格式化异常"); System.out.println(nfe); //toString方法 ClassCastException cce = new ClassCastException("类型转换异常"); System.out.println(cce); ArrayIndexOutOfBoundsException aobe = new ArrayIndexOutOfBoundsException("数组下标越界异常"); System.out.println(aobe); NullPointerException npe = new NullPointerException("空指针异常"); System.out.println(npe); } }
package Advance.exception; public class ExceptionTest02 { public static void main(String[] args) { System.out.println(100/0); /** * 程序执行到此发生了ArithmeticException异常 * 底层new ArithmeticException异常对象 * 然后抛出ArithmeticException给main方法 * main方法没有处理,将这个异常自动抛给JVM * jvm最终终止程序执行 所不会输出hello world * * ArithmeticException属于运行时异常 */ System.out.println("hello world !"); } }
package Advance.exception; /** * @author 衣鱼 * doSome()方法调用报错的原因是什么? */ public class ExceptionTest03 { //第一种处理:在方法声明上继续使用throws ,来完成异常的继续上抛 ,抛给调用者 //上抛类似推卸责任 ,将异常抛给调用者 //public static void main(String[] args) throws ClassNotFoundException { /** * main方法调用doSome()方法 * 因为doSome()方法声明位置上有throws ClassNotFoundException * 所以在调用doSome()方法时,必须对异常进行预先处理 * 如果不处理,编译器会报错 */ // doSome(); //编译器报错 :Unhandled exception type ClassNotFoundException // } //第二种方式 try ......catch 进行捕捉 //捕捉相当于把异常拦下来,上层不知道 public static void main(String[] args) { try { doSome(); }catch(ClassNotFoundException e) { e.printStackTrace(); } } /** * doSome方法在方法声明的位置使用了throws ClassNotFoundException * 这个代码表示doSome()方法在执行过程中,可能出现ClassNotFoundException异常 * ClassNotFoundException的父类属于Exception,所以 ClassNotFoundException属于编译时异常 * @return * @throws ClassNotFoundException */ public static void doSome() throws ClassNotFoundException{ //System.out.println("dosome !"); } }
package Advance.exception; import java.io.FileInputStream; import java.io.FileNotFoundException; /** * @author 衣鱼 * */ public class ExceptionTest04 { public static void main(String[] args) { System.out.println("main begin"); m1(); System.out.println("main over"); } private static void m1() { System.out.println("m1begin"); m2(); System.out.println("m1over"); } private static void m2() { System.out.println("m2begin"); m3(); System.out.println("m2over"); } private static void m3() { //调用sun jdk的构造方法 /** * 运行报错 * 该处调用了一个构造方法: FileInputStream(); * 该方法的源代码声明位置上有:throws FileNotFoundException * 通过类的继承结构看到:FileNotFoundException 父类是IOException * IOException的父类Exception,所以,FileNotFoundException是编译时异常 * * 编译时异常要求程序员编写程序对该程序进行处理,不处理就会报错。 */ //new FileInputStream("C:\\Users\\衣鱼\\Desktop\\课后题.docx"); //创建一个输入流对象,该流指向一个文件 try { new FileInputStream("C:\\Users\\衣鱼\\Desktop\\课后题.docx"); //创建一个输入流对象,该流指向一个文件 }catch(FileNotFoundException ffe) { //往上写父类没有问题 System.out.println("文件未找到"); } } }
package Advance.exception; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; /** * @author 衣鱼 * 异常捕捉的情况下,方法的后续代码照样执行。 * 异常上抛的情况下,方法的后续代码不再执行。 * * try catch * 1、catch后的小括号中的类型可以是具体的异常类型,也可以是该异常类型的父类型 * 2、catch可以写多个,建议精确到一个个处理,有利于程序调试 * 3、catch多个情况处理时,从上到下必须遵从从小到大的原则。先子类再父类。 */ public class ExceptionTest04 { public static void main(String[] args) { System.out.println("main begin"); m1(); System.out.println("main over"); } private static void m1() { System.out.println("m1begin"); m2(); System.out.println("m1over"); } private static void m2() { System.out.println("m2begin"); m3(); System.out.println("m2over"); } private static void m3() { //调用sun jdk的构造方法 /** * 运行报错 * 该处调用了一个构造方法: FileInputStream(); * 该方法的源代码声明位置上有:throws FileNotFoundException * 通过类的继承结构看到:FileNotFoundException 父类是IOException * IOException的父类Exception,所以,FileNotFoundException是编译时异常 * * 编译时异常要求程序员编写程序对该程序进行处理,不处理就会报错。 */ //new FileInputStream("C:\\Users\\衣鱼\\Desktop\\课后题.docx"); //创建一个输入流对象,该流指向一个文件 try { new FileInputStream("C:\\Users\\衣鱼\\Desktop\\课后题.docx"); //创建一个输入流对象,该流指向一个文件 }catch(FileNotFoundException ffe) { System.out.println("文件未找到"); } try { new FileInputStream("C:\\Users\\衣鱼\\Desktop\\随机算法.docx"); //创建一个输入流对象,该流指向一个文件 }catch(FileNotFoundException ffe) { System.out.println("文件未找到"); }catch(IOException ie) { System.out.println("读文件报错"); } } }
package Advance.exception; import java.io.FileInputStream; import java.io.FileNotFoundException; /** * @author 衣鱼 * 异常对象的重要方法 * String msg = exception.getMessage(); //获取异常简单的描述信息 * exception.printStackTrace(); //打印异常追踪的堆栈信息 */ public class ExceptionTest05 { public static void main(String[] args) { NullPointerException e = new NullPointerException("空指针异常dfhhediue"); //new异常对象,但没有抛出 不会中断程序 //获取异常信息,构造方法的String参数 String msg = e.getMessage(); //空指针异常dfhhediue System.out.println(msg); //打印异常堆栈信息 e.printStackTrace(); //后台打印信息的时候,采用了异步线程的方式 System.out.println("hello world "); m1(); } private static void m1() { m2(); } private static void m2() { m3(); } private static void m3() { //自动生成try catch try { new FileInputStream("C:\\Users\\衣鱼\\Desktop\\课后题.docx"); } catch (FileNotFoundException e) { //System.out.println("文件未找到"); e.printStackTrace(); //异常追踪信息 System.out.println("======================================="); String msg = e.getMessage(); System.out.println(msg); } } }
package Advance.exception; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; /** * @author 衣鱼 * 关于try catch中的finally子句: * 1、在finally子句中的代码最后执行,并且一定会执行,即使try语句块代码出现异常 * 2、finally语句必须和try一起出现,不能单独编写 * 3、finally子句的适用情况:通常在finally语句块完成资源的释放/关闭。 */ public class ExceptionTest06 { public static void main(String[] args) { FileInputStream fs = null; //声明位置放在try的外面,这样在finally中才能使用 try { fs = new FileInputStream("C:\\Users\\衣鱼\\Desktop\\课后题.docx"); //空指针异常 String s = null; s.toString(); System.out.println("+++++======+++++++"); //不会在控制台输出,因为空指针异常;所以try中以后的代码也不会执行 //关闭流 流不关闭还是需要占用资源的 //目标:即使上面的程序出现异常,流仍然需要关闭 //fs.close(); }catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { //关闭流 // TODO Auto-generated catch block e.printStackTrace(); }finally { //finally的代码一定会执行,即使try出现异常 //将关闭流的代码放入finally更适合 if(fs!=null){ //fs.close(); //IO异常,进行捕捉 try { fs.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } System.out.println("................................................................."); //输出,finally语句中都会执行 } } }
package Advance.exception; /** * @author 衣鱼 * finally的深层次理解 * try中的return和fianlly执行顺序 */ public class ExceptionTest07 { public static void main(String[] args) { //try finally 没有catch 是可以的 /* //代码的执行顺序: //先执行try //再执行finally //最后执行return [return执行,方法必然结束] try { System.out.println("try......"); return; //finally内的代码块依旧会执行 }finally { System.out.println("finally......"); } //System.out.println("==============="); //代码不会执行 */ try { System.out.println("try......"); //退出jvm System.exit(0); //退出jvm finally不会执行 }finally { System.out.println("finally......"); } } }
package Advance.exception; /** * @author 衣鱼 * 面试题: * 输出结果是什么?——100 * *java语法规则: * 方法体中的代码必须遵循自上而下的顺序依次执行 * return语句一旦执行,整个方法必须结束 */ public class ExceptionTest08 { public static void main(String[] args) { int result = m(); System.out.println(result); } public static int m() { int i =100; //流程① try { //这行代码出现在int i= 100 后面 所以最终返回必须是100 //return一定是最后执行的,一旦执行,整个方法结束 return i; //流程③ }finally { i++; //流程② } } /* m()反编译之后的效果 public static int m() { int i =100; int j = i; i++; return j; } */ }
package Advance.exception; /** * @author 衣鱼 * */ public class ExceptionTest09 { public static void main(String[] args) { //final 是一个关键字 表示最终的不变的 final int i =100; //finally 是一个关键字 和try联合使用 //finalize 是Object类中的一个方法 作为一个方法名存在 //标识符 该方法由垃圾回收器调用 } }
见Object文章
package Advance.exception; /** * @author 衣鱼 * 自定义异常 * 异常类型:MyException * 父类: Exception */ public class MyException extends Exception { public MyException() { } public MyException(String s) { } } package Advance.exception; /** * @author 衣鱼 * 测试自定义的异常类 */ public class MyExceptionTest { public static void main(String[] args) { MyException me = new MyException("用户名不能为空"); //调用自定义的异常测试程序的时候需要throw出去 //throw me; //如果自定义异常是编译时异常,需要进行预处理,此时我们刚抛出去异常,不能在使用catch捕捉,在方法上继续throws me.printStackTrace(); } }
package homework; /** * @author 衣鱼 * 编写程序模拟用户注册 * 1、程序执行,需要用户输入”用户名“、”密码“ * 2、输入信息后。后台java程序模拟用户注册 * 3、注册用户名要求长度【3-10】之间。其他为异常 * */ public class Register { public static void main(String[] args) { UserServise us = new UserServise(); try { us.register(args[0],args[1]); } catch (MyUserException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } /** * * @author 衣鱼 * username 用户名 * password 密码 * 当用户名为空、用户名小于3位、用户名大于10位 出现MyUserException 异常 */ class UserServise{ public void register(String username ,String password) throws MyUserException { //引用等于null判断最好放在最前面 //username == null 不如写成 null==username 考虑到程序员失误,把双等于写成一个赋值等于 if(null ==username||username.length()<3||username.length()>10) { //MyUserException mue =new MyUserException("注册用户名要求长度【3-10】之间"); //throw mue; throw new MyUserException("注册用户名要求长度【3-10】之间"); }else { System.out.println("注册成功"); } } } //自定义异常类 class MyUserException extends Exception{ public MyUserException() { } public MyUserException(String s) { super(s); } }