Java学习 - 异常

Java 异常

Java语言是安全的,根据错误的性质,Java语言将运行错误分为两类: 错误异常

错误(Error)

错误是指程序运行时遇到的硬件的错误,或操作系统,虚拟机等系统软件错误,或操作错误. 错误对于程序而言是致命的,错误将导致程序无法继续运行.

java.lang.Error是错误类,当产生错误时,Java虚拟机抛出Error类对象. 主要的错误有:

  • NoClassDefFoundError : 类定义未找到错误.当没有找到.class文件或运行没有main()方法的.class类会抛出.
  • OutOfMemoryError: 内存溢出. 当用new分配内存且没有可用内存时抛出.
  • StackOverflowError : 栈溢出.递归过深抛出.

Java程序本身不能对错误进行处理,只能依靠外界干预.

异常(Exception)

异常是指在硬件,操作系统或虚拟机等系统软件运行正常时,程序产生的运行错误(语义错误). 例如,整数进行除法运算时除数为0,操作数超过数据范围,输入数据格式错误,打开一个文件时发现文件不存在,网络连接中断,数据库连接中断等.

异常对于程序而言是非致命的,异常处理机制能够使程序捕获和处理异常,由异常处理代码调整程序运行方向继续运行.

1. 异常类

java.lang.Exception异常类是Java语言定义的所有异常类所构成树层次结构的根类,其他异常类是Exception的子类或后代类

Java语言定义的异常类主要分为运行异常非运行异常.

  • RuntimeException 运行异常
  • ArithmetException 算数异常
  • NullPointerException 空对象异常
  • ClassCastException 强制类型转换异常
  • NegativeArraySizeException 负数数组长度异常
  • ArrayIndexOutOfBoundsException 字符串序号越界异常
  • NumberFormatException 数值格式异常

2. 异常处理措施

Java语言的异常处理机制包括异常类体系,异常处理的try语句,抛出自定义异常对象的throw语句,声明方法抛出异常的throws子句和自定义异常类. 这些功能不仅能够捕获处理异常,还能够主动抛出异常,也能够将异常传递给调用者.

  • 创建一个异常类对象的过程称为抛出异常
  • 获得异常对象的过程称为捕获异常
  • 对异常对象执行操作的过程称为处理异常

3. 异常处理语句

try{
	[存在潜在异常的语句]
}catch([异常类] [异常对象]){
	[捕获到异常对象并进行处理的语句]
}finally{
    [最后必须执行的语句: 无论是否抛出了异常,是否捕获到异常]
}

其中,try,catch,finally是关键字,catch子句可以有多个,finally子句可以省略

try-catch-finally将正常执行语句与异常处理语句分离,增强了程序的可读性

  • try子句包含可能抛出异常的语句序列.
  • catch子句捕获并处理指定类型的异常对象,参数是Exception类及其子类的实例,多个catch子句可以分别处理多种不同类型的异常对象.
  • finally 子句包含最后必须执行的语句.

e.g 数值格式异常处理

public class IntArray5{
    public static int[] getIns(String[] str){
        if(str==null || str.length == 0)
            return null;
        int[] x = new int[str.length];
        int n=0,i=0;
        while(i < str.length){
            try{
                x[n] = Integer.parseInt(str[i]);
                ++n;
            }catch(NumberFormatException ex){
                System.out.println("\"" + str[i] + "\"" + ex.toString());
            }catch(Exception ex){
                ex.printStack();
            }finally{
                i++;
            }
        }
        
        if(n==x.length)
    		return x;
        int[] y=new int[n];
        System.arraycopy(x,0,y,0,n);
        return x;
    }	
}

4. 抛出异常

4.1 抛出异常对象的throw语句

异常对象可以由Java虚拟机抛出,也可以由程序主动抛出. 如果程序中存在逻辑错误但不是Java的异常,程序也可以采用throw语句主动抛出一个异常对象.throw语句抛出一个异常对象,语法格式如下

throw [异常对象]

e.g 抛出逻辑异常

public void set(int year,int month,int day){
	if(month < 1 || month > 12)
        throw new Exception("月份错误");
}

4.2 方法声明抛出异常的throws子句

如果一个方法抛出异常,而该方法没有能力处理该异常,则可以在方法声明时,采用throws子句声明该方法将抛出异常. 带有throws子句声明该方法将抛出异常. 带有throws子句的方法声明语法格式如下,其中throws时关键字,"异常类列表"是该方法要抛出的异常类,多个异常类用","分隔. throws子句不是一条独立的语句.

[修饰符] 返回值类型 方法([参数列表]) [throws 异常类列表]

例如,上述set()方法体中抛出异常,如果该方法体内没有处理异常,那么set()方法必须使用throws子句声明抛出异常如下

public void set(int year,int month,int day)throws Exception{
	if(month<1 || month > 12)
        throw new Exception("月份错误")
}

这么写后,抛出的异常由该方法的调用者处理; 如果调用者也无法处理,那么调用者也需要声明throws子句.

定义异常类

前述set()方法通过throw语句抛出的Exception异常只能够在以下catch子句中被捕获:

catch(Exception ex){
	if(ex.getMessage().equals("月份错误"));
}

// ex.getMessage() 返回一个字符串,表示异常信息的类别

而当Java语言提供的异常类不能满足需要时,更好的方法是,应用程序自定义异常类,由catch语句捕获并处理.自定义异常类必须是Exception的子类.

e.g 自定义异常类,日期类的异常处理

public class DateFormatException extends IllegalArgumentException{
    public DateFormatException(String message){ super(message); }
    public DateFormatException(){ super(); }
}

相应的,set()方法应该修改如下

public void set(int year,int month,int day)throws DateFormatException{
    if(year<=-2000 || year > 2500)
        throws new DateFormatException(year+",年份不合适,有效年份为-2000~2500.");
    if(month < 1 || month > 12)
        throws new DateFormatException(month+"月,月份错误");
    if(day < 1 || day > MyDate.daysOfMonth(year,month))
        throws new DateFormatException(year+"年"+month+"月"+day+"日,日期错误");
    
    this.year=year;
    this.month=month;
    this.day=day;
}
posted @ 2020-11-20 18:15  popozyl  阅读(131)  评论(0编辑  收藏  举报