异常
异常又称为例外,是一个在程序执行期间发生的事件,它中断正在执行程序的正常指令流
异常的类型:
运行时异常(RuntimeException)和编译时异常(非运行异常)
编译异常处理的方式:
try…catch对异常进行捕获处理。
throws 关键字声明异常,让调用者对其处理。
运行时异常
由jvm自行捕获处理,即使没有try…catch语句捕获或用throws关键字抛出,程序也能编译通过,只是在运行过程中可能报错。
五种常见运行时异常
ArithmeticException 算数运行异常
IndexOutOfBoundsException 角标越界异常
ClassCastException 类型转换异常
NullPointerException 空指针异常
NumberFormatException 数字格式化异常
我们把生成异常对象,并把它提交给运行时系统的过程称为拋出(throw)异常。
运行时系统在方法的调用栈中查找,直到找到能够处理该类型异常的对象,这一个过程称为捕获(catch)异常。
处理异常
常处理通过 5 个关键字来实现:try、catch、throw、throws 和 finally。
try catch 语句用于捕获并处理异常。
finally 语句用于在任何情况下(除特殊情况外)都必须执行的代码。
捕获异常
try {
// 可能会发生异常的语句
} catch(Exception 类或者子类 e) {
// 处理异常语句
} finally {
// 清理代码块
}
当try
当中没有异常语句时,程序跳出try{}catch{}
执行下面的程序,如果try
当中有异常语句的时候,catch
进行捕获,执行catch
当中的语句,当然无论发生异常与否finally
都会被执行。
public class Example {
public static int divide (int x ,int y){
try{
int result=x/y;
return result;
}catch (Exception e){
System.out.println("捕获的异常信息为:"+e.getMessage());
}finally {
System.out.println("执行final代码块,无论程序是否异常,都会执行");
}
return -1;
}
public static void main(String [] args){
int result=divide(4,0);
if(result==-1){
System.out.println("程序异常");
}else{
System.out.println(result);
}
}
}
使用 try-catch-finally 语句时需注意以下几点:
- 异常处理语法结构中只有 try 块是必需的,如果没有 try 块,则不能有后面的 catch 块和 finally 块;
- catch 块和 finally 块都是可选的,但 catch 块和 finally 块至少出现其中之一,也可以同时出现;
- 可以有多个 catch 块,捕获父类异常的 catch 块必须位于捕获子类异常的后面;
- finally 与 try 语句块匹配的语法格式,此种情况会导致异常丢失,所以不常见。
抛出异常
抛出异常:程序在检查(编译)的时候,将可能出现的错误抛出,不做处理。
throw和throws的区别
throw 用于方法体内,并且抛出的是一个异常类对象。(用于拋出异常)
throws 用于方法声明后,声明该方法要拋出的异常,并且抛出的是异常类。
throw和throws语法
throws
[修饰符] 返回值类型 方法名(参数类型1..) throws 异常类 1,异常类2,....{ 方法体..... }
public class Animal {
public static int test1(int a ,int b) throws Exception{
int result =a/b;
return result;
}
public static void main (String [] args) throws Exception{
Animal animal=new Animal();
int result=Animal.test1(1,0);
}
}
虽然编译通过,但是运行错误。
可以通过捕获将其处理,让运行通过
public class Animal {
public static int test1(int a ,int b) throws Exception{
int result =a/b;
return result;
}
public static void main (String [] args) {
try {
Animal animal = new Animal();
int result = Animal.test1(1, 0);
}catch(Exception e) {
System.out.println("异常信息为:"+e.getMessage());
}
}
}
throw
[修饰符] 返回值类型 方法名(参数类型1..) throws 异常类 1,异常类2,....{ 方法体.....
throw new Exception 类或其子类的构造方法;
}
public class Animal {
public static void test1(int age) throws Exception{
if (age <0){
throw new Exception("输入的年龄必须时正数");
}else{
System.out.println("此人的年龄为"+age);
}
}
public static void main (String [] args) {
try {
Animal animal = new Animal();
Animal.test1(-1);
}catch(Exception e) {
System.out.println("异常信息为:"+e.getMessage());
}
}
}
public class Animal {
public static void test1(int age) throws Exception{
if (age <0){
throw new Exception("输入的年龄必须时正数");
}else{
System.out.println("此人的年龄为"+age);
}
}
public static void main (String [] args) throws Exception {
Animal animal = new Animal();
Animal.test1(-1);
}
}
当 throw 语句执行时,它后面的语句将不执行,此时程序转向调用者程序,寻找与之相匹配的 catch 语句,执行相应的异常处理程序。如果没有找到相匹配的 catch 语句,则再转向上一层的调用程序。这样逐层向上,直到最外层的异常处理程序终止程序并打印出调用栈情况。throw 关键字不会单独使用。
自定义异常
自定义的异常类只需要继承Exception类,在构造方法中使用super()语句调用Exceptiond的构造方法即可
自定义异常的语法形式为:
<class><自定义异常名><extends><Exception>
class MytestException extends Exception{
public MytestException(){
super();
}
public MytestException(String message){
super(message);
}
}
public class Animal {
public static int test1(int a,int b) throws MytestException{
if (b==0){
throw new MytestException("输入数不能时0");
}else{
return a/b;
}
}
public static void main (String [] args) {
try {
int result=test1(4,0);
System.out.println(result);
}catch(MytestException e) {
System.out.println("异常信息为:"+e.getMessage());
}
}
}
在编码规范上,一般将自定义异常类的类名命名为 XXXException,其中 XXX 用来代表该异常的作用。
自定义异常类一般包含两个构造方法:一个是无参的默认构造方法,另一个构造方法以字符串的形式接收一个定制的异常消息,并将该消息传递给超类的构造方法。
Lambda
这种表达式只针对有一个抽象方法的接口实现,用来实现接口功能作为方法参数。
语法格式:
([数据类型 参数类型, 数据类型 参数类型......]->{表达式主体}
public class Main {
public static void main(String[] args) {
// write your code here
ceshi ce=(int a,int b)->{
return a+b;
};
System.out.println(ce.add(1,2));
}
interface ceshi{
abstract int add(int a,int b);
}
}
使用接口类型数据ce去调用接口内地函数,当我使用Main类去实现这个接口时,爆出没有实现接口中的抽象函数。