JavaSE学习笔记(九)(异常)

    科技2022-07-10  110

    异常

    异常本身是一个类,产生异常就是创建异常对象并抛出一个异常对象。 Throwable是超类 java.lang.Throwable:所有错误或者异常的超类 两个子类: 1.Exception:编译期异常,进行编译(写代码)java程序出现的异常 2.RuntimeException:运行期异常,java程序运行时期的异常 异常就是小毛病,把异常处理掉,程序可以继续执行 Error:错误 相当于程序得了一个无法治愈的毛病,必须修改源码

    编译异常: 方法一:

    public class demo1 { public static void main(String[] args) throws ParseException {//把异常跑出去,交给虚拟机来处理 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");//格式化日期 Date date = sdf.parse("1999-02-09");//如果格式不对,jvm会中断运行,把异常打印 System.out.println(date); } }

    方法二:

    public class Dem02 { public static void main(String[] args) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");//格式化日期 Date date = null; try {//这种处理了异常之后,会继续执行代码 date = sdf.parse("1999-0223"); } catch (ParseException e) { e.printStackTrace(); } System.out.println(date); System.out.println("后续代码");//null //后续代码 } }

    运行期出现异常

    public class Yunxing { public static void main(String[] args) { int [] a = {1,2,3}; try{//可能出现异常的代码 System.out.println(a[3]); } catch (Exception e){//异常处理逻辑 System.out.println(e); //java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3 } System.out.println("后续代码");//后续代码 } }

    Error错误:

    public class Demo { public static void main(String[] args) { int [] a = new int[1024*1024*1024];//内存溢出 System.out.println("后续代码"); } }

    ==================================================================

    异常产生过程解析

    ==============================================================

    异常的处理

    五个关键字:try/catch/finally/throw/throws

    throw关键字: 作用:用关键字在指定的方法中抛出指定异常 使用格式:throw new xxxException(异常产生的原因) 注意: 1关键字必须写在方法内部 2.后面new的对象必须是Exception或者是Exception的子类对象 3.关键字抛出指定异常,我们必须处理这个异常 关键字后面创建的是RuntimeException或者是RuntimeException子类对象,我们可以不处理,交给JVM处理(打印异常对象,中断程序) 创建的是编译异常,我们必须处理,要么throws要么try。。。catch。。

    public class Throw { public static void main(String[] args) { int [] a = null; int aa = nul(a,0); System.out.println(aa); } public static int nul(int[] a,int m){ if(a==null){ throw new NullPointerException("空指针异常");//运行期异常可以不用处理 } else if(m<0||m>2){ throw new ArrayIndexOutOfBoundsException("超出索引"); } return a[m]; } }

    =====================================

    Objects非空判断

    public class Objects { public static void main(String[] args) { s(null); } public static void s(Object obj){ if(obj==null){ throw new NullPointerException("空指针"); } // Objects.requireNonNull(obj); } }

    ======================================== 第一种处理异常:throws关键字(交给别人处理) 格式:

    修饰符 返回值类型 方法名(参数) throws AAAExcepton,BBBExcepton.{ throw new AAAExcepton(“产生原因”); throw new BBBExcepton(“产生原因”);

    }

    注意事项: 1.throws关键字必须写在方法声明处 2.throws后边声明的异常必须是Exception或者子类 3.如果抛出的多个异常有父子类关系,那么值声明异常即可 4.调用一个声明抛出异常的方法,我们必须处理声明的异常。要么使用throws声明抛出, 要么try…catch自己处理

    public class Demo { public static void main(String[] args) throws FileNotFoundException { m("d://a.txt"); } public static void m(String file) throws FileNotFoundException { //FileNotFoundException是编译异常,抛出了编译异常就必须处理这个异常 //可以调用throws继续声明抛出FileNotFoundException这个异常对象,让方法调用者处理 if(!file.equals("d://a.tzt")){ throw new FileNotFoundException("没有找到文件"); } System.out.println("后续代码");//不能被打印,JVM中断 } }

    ====================================================== 第二种处理异常 捕捉异常 try…catch

    格式:

    try{ 可能产生异常的代码 }catch(定义一个异常的变量,用来接收try中抛出的异常){ 异常处理逻辑 一般工作中,把异常信息记录到一个日志中 } … catch(异常类名 变量名){ }

    注意:1.try可以抛出多个异常,用多个catch来处理这些异常对象

    public class Demo { public static void main(String[] args) { try{ m("d://a.bat"); }catch(IOException e){ System.out.println("catch-传递文件后缀不是.txt"); } System.out.println("后续代码"); } public static void m(String file) throws IOException { if(!file.endsWith(".txt")){ throw new IOException("后缀不对"); } } } //catch-传递文件后缀不是.txt //后续代码

    ====================================================================

    Throwable类中定义的三个异常处理的方法

    String getMessage() 返回此 throwable 的详细消息字符串 String toString() 返回此 throwable 的简短描述。 。 void printStackTrace() JVM打印异常对象,默认此方法,打印的异常信息是最全面的

    public class Demo { public static void main(String[] args) { try{ m("d://a.bat"); }catch(IOException e){ // System.out.println("catch-传递文件后缀不是.txt"); //System.out.println(e.getMessage());//打印:后缀不对 //System.out.println(e.toString());//打印:java.io.IOException: 后缀不对 e.printStackTrace();//java.io.IOException: 后缀不对 //at javayichang.trycatch.Demo.m(Demo.java:22) //at javayichang.trycatch.Demo.main(Demo.java:9) //后续代码 } System.out.println("后续代码"); } public static void m(String file) throws IOException { if(!file.endsWith(".txt")){ throw new IOException("后缀不对"); } } }

    ============================================================ finally代码块

    格式:try{ } catch(){ } finally{ 无论是否出现异常,都会被执行; }

    public class Finall { public static void main(String[] args) { try { readfile("d;//a.txt"); } catch (IOException e) { e.printStackTrace(); }finally { System.out.println("资源释放");//输出 } } public static void readfile(String filename) throws IOException { if(!filename.endsWith("txt")) { throw new IOException(); } } }

    ======================================================

    多个异常

    public class Demo1 { public static void main(String[] args) { //1.多个异常,逐个处理 /*try { int[] a = {1, 2, 3}; System.out.println(a[3]); } catch (ArrayIndexOutOfBoundsException e) { // e.printStackTrace(); System.out.println(e.getMessage());//Index 3 out of bounds for length 3 } try{ ArrayList<Integer> integers = new ArrayList<>(); integers.add(1); System.out.println(integers.get(4)); }catch(IndexOutOfBoundsException e){ //e.printStackTrace(); System.out.println(e.getMessage());//Index 4 out of bounds for length 1 } System.out.println("后续代码");//后续代码 */ //2.多个异常,一次捕捉,多次处理 //注意:如果存在子父类,那么子类必须在上面 //ArrayIndexOutOfBoundsException extends IndexOutOfBoundsException /*try { int[] a = {1, 2, 3}; System.out.println(a[3]); ArrayList<Integer> integers = new ArrayList<>(); integers.add(1); System.out.println(integers.get(4)); } catch (ArrayIndexOutOfBoundsException e) { // e.printStackTrace(); System.out.println(e.getMessage());//Index 3 out of bounds for length 3 }catch(IndexOutOfBoundsException h){ //e.printStackTrace(); System.out.println(h.getMessage()); } System.out.println("后续代码");//后续代码 */ //一次捕获异常,一次处理异常 try { int[] a = {1, 2, 3}; System.out.println(a[3]); ArrayList<Integer> integers = new ArrayList<>(); integers.add(1); System.out.println(integers.get(4)); } catch (ArrayIndexOutOfBoundsException e) {//父类,可以接收自己的对象,也可以接收子类对象。 // e.printStackTrace(); System.out.println(e.getMessage());//Index 3 out of bounds for length 3 } System.out.println("后续代码");//后续代码 } } //运行期异常可以不用处理,交给虚拟机处理

    ====================================================== finally中有return语句,则永远返回finally中的return对象

    public class finanlly { public static void main(String[] args) { int num =get(); System.out.println(num);//100 } public static int get(){ try{ int a=10; }catch(Exception e){ System.out.println(e.toString()); }finally { int a = 100; return a; } } }

    ======================================================

    子父类异常

    1.如果父类抛出多个异常,子类重写父类该方法时,抛出和父类相同的异常或者父类异常的子类或者不抛出 2.父类方法没有抛出异常,子类重写父类该方法时也不能抛出异常,此时子类产生异常,只能捕获处理,不能抛出

    public class FU { public void show01() throws NullPointerException,ClassCastException{} public void show02() throws IndexOutOfBoundsException{} public void show03() throws IndexOutOfBoundsException{} public void show04(){} } class Zi extends FU{ //子类重写父类异常时,抛出和父类相同的异常 public void show01() throws NullPointerException,ClassCastException{} //子类重写父类方法时,抛出父类异常的子类 public void show02() throws ArrayIndexOutOfBoundsException{} //子类重写父类异常时,不抛出异常 public void show03(){} //父类没有抛出异常,子类重写父类该方法时也不能抛出 //如果子类产生异常,只能捕获,不能抛出 public void show04(){ try{ throw new Exception("编译期异常"); }catch(Exception e){ e.printStackTrace();; } } }

    ================================================================

    自定义异常类

    java提供的异常类不够我们使用,需要自己定义一些异常类 格式:

    注意: 1.自定义异常类一般都是以Exception结尾,说明类是一个异常类 2.自定义异常类,必须继承Exception或者RuntimeException 继承Exception,那么自定义的类就是编译器异常,如果方法内部抛出了编译期异常,就必须处理这个异常,要么throws要么try。。。catch。。 继承RuntimeException,那么定义的异常类就是一个运行期异常,无需处理,交给虚拟机处理(中断)

    public class RegisterException extends Exception{ //添加一个空参数的构造方法 public RegisterException(){ } //添加一个带异常信息的构造方法 public RegisterException (String messsge){ super(messsge); } }

    ===================================================

    自定义异常类练习

    模拟注册操作,如果用户名存在,抛出异常提示, 分析: 1.使用数组保存已经注册过的用户名(数据库) 2.使用Scanner获取用户输入的用户名(前端,页面) 3.定义一个方法,对用户输入的名字进行判断

    public class RegisterException extends Exception{ //添加一个空参数的构造方法 public RegisterException(){ } //添加一个带异常信息的构造方法 public RegisterException (String messsge){ super(messsge); } } public class Demo01 { static String[] usernames = {"张三","李四","王五"}; public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.println("请输入用户名"); String username = sc.next(); check(username); } public static void check(String username){ for (String name : usernames) { if(name.equals(username)){ try { throw new RegisterException("亲,该用户名已经被注册"); } catch (RegisterException e) { e.printStackTrace(); return; } } } System.out.println("注册成功"); } }
    Processed: 0.014, SQL: 8