一、引入
public static void main(String[] args) {
//键盘录入俩个数,求商
Scanner sc=new Scanner(System.in);
System.out.println("请录入第一个数");
int num1=sc.nextInt();
System.out.println("请录入第二个数");
int num2=sc.nextInt();
System.out.println("商:"+num1/num2);
}
正常:
异常1:
录入了非int数据
异常2:
异常3
除数为0的时候
定义:Exception在程序运行的过程中,发生了不正确的现象,阻止了程序的运行,称之为发生异常
二、if-else处理异常
public static void main(String[] args) {
//键盘录入俩个数,求商
Scanner sc=new Scanner(System.in);
System.out.println("请录入第一个数");
//判断录入的数是否是整数
if(sc.hasNextInt()){
//先判断在录入
int num1=sc.nextInt();
System.out.println("请录入第二个数");
if(sc.hasNextInt()){
int num2=sc.nextInt();
if(num2==0){
System.out.println("对不起,您输入的除数不能为0");
}else{
System.out.println("商:"+num1/num2);
}
}else {
System.out.println("对不起,你录入的不是int类型的数据");
}
}
else{
System.out.println("对不起,你录入的不是int类型的数据");
}
}
测试:
缺点:代码臃肿,业务代码和处理异常的代码混在一起,可读性差,不好维护,难以解决所有异常
三、异常处理机制
1.查看异常
第一行提示异常出现的原因,最后一行异常出现的位置
2.捕获异常
把可能出现异常的代码放入try代码块中,然后将异常封装为对象,被catch()中异常对象接受,接受以后,原样执行try-catch后面的代码
try中没有异常,catch中的代码不执行,try中有异常
注意:try中出现异常,然后用catch捕获成功,try中后续的代码不会执行
catch捕捉异常成功,后续代码继续执行
public static void main(String[] args) {
try{
Scanner sc=new Scanner(System.in);
System.out.println("第一个数");
int num1=sc.nextInt();
System.out.println("第二个数");
int num2=sc.nextInt();
System.out.println("商:"+num1/num2);
}catch (Exception ex){
System.out.println("对不起,程序异常");
}
System.out.println("谢谢使用");
}
四、catch中处理异常的方式
1.不处理
2.用户自定义异常信息
3.打印异常信息
(1)调用toString方法
(2)显示异常信息对应的字符串,没有就输出null
(3)显示异常的堆栈信息,将异常信息捕获后在控制台将异常信息所有打印出来
4.抛出异常
public static void main(String[] args) {
try{
Scanner sc=new Scanner(System.in);
System.out.println("第一个数");
int num1=sc.nextInt();
System.out.println("第二个数");
int num2=sc.nextInt();
System.out.println("商:"+num1/num2);
}catch (Exception ex){
//1.不处理
//2.输出提示
System.out.println("对不起,程序异常");
//3.打印异常信息
//调有toString方法
System.out.println(ex);
System.out.println(ex.toString());
//显示异常描述信息对应的字符串,没有就是null
System.out.println(ex.getMessage());
//显示异常的堆栈信息,将异常信息捕获后在控制台将异常信息所有打印出来
ex.printStackTrace();
//4.抛出异常
throw ex;
}
System.out.println("谢谢使用");
}
五、finally
1.try-catch不执行
(1)throw抛出异常
(2)catch没有进行正常的异常捕捉
(3)在try中与到return
2.如何保证try-catch后面的的代码一定执行
3.return和finally执行顺序
先执行finally在执行return
4.什么代码会放在finall中
关闭数据库资源,关闭IO流资源,关闭socket资源
5.可以不执行finall中的代码
System.exit(0);//终止当前虚拟机执行
六、多重catch
1.try出现异常以后,将异常类型和catch后面的类型依次比较,按照代码的顺序进行对比,执行第一个与异常类型匹配的catch语句
2.一旦执行其中一条catch语句,后面的catch就会被省略不运行
3.安排catch语句时,将特殊异常放在前面,先写子类异常,再写父类异常
public static void main(String[] args) {
try{
Scanner sc = new Scanner(System.in);
System.out.println("第一个数");
int num1 = sc.nextInt();
System.out.println("第二个数");
int num2 = sc.nextInt();
System.out.println("商:" + num1 / num2);
}catch(InputMismatchException ex){
System.out.println("您输入的不是int类型的数据");
}catch (ArithmeticException ex){
System.out.println("除数不可以为0");
}catch (Exception ex){
System.out.println("出现异常");
}
finally {
System.out.println("谢谢使用");
}
}
七、异常的分类、层次结构
程序中的语法错误、逻辑错误不属于异常和错误
运行异常
public static void main(String[] args) {
int[] arr={1,2,3};
System.out.println(arr.length);
int[]arr2=null;
System.out.println(arr2.length);
}
检查异常:
处理方式1
public static void main(String[] args) {
try {
try {
Class.forName("aaaaa").newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
处理方式2(自立更生法)
public static void main(String[] args) {
try {
Class.forName("aaaaa").newInstance();
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
}
处理方式3(甩锅法)
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
Class.forName("aaaaa").newInstance();
}
八、throw和throws的区别
(1)位置
throw:定义在方法内部
throws:定义在方法的签名出(声明处)
(2)内容
throw+异常对象(检查异常,运行时异常)
throws+异常的类型
(3)作用
throw:异常出现的源头,制造异常
throws:在方法的声明处,告诉方法的调用者,这个方法可能会出现声明的这些异常,调用调用这个异常的时候进行处理,要么自己处理,要么向外抛出异常
Scanner sc=new Scanner(System.in);
int num1=sc.nextInt();
int num2=sc.nextInt();
if(num2==0){
/* //制造运行时异常
throw new RuntimeException();
*/
//检查异常
try {
throw new Exception();
} catch (Exception e) {
e.printStackTrace();
}
}else{
System.out.println("商:"+num1/num2);
}
}
如何处理异常
public void setSex(String sex) throws Exception {
if(sex.equals("男")||sex.equals("女")){
this.sex=sex;
}else{
//1.默认值
//this.sex="男";
//2.友好提示
System.out.println("对不起你的性别错了");
//3.制造运行时异常
//throw new RuntimeException("性别不对")
//4.制造检查异常
/*try {
throw new Exception();
} catch (Exception e) {
e.printStackTrace();
}*/
throw new Exception();
}
}
public Student(String name, int age, String sex) {
this.name = name;
this.age = age;
try {
this.setSex(sex);
} catch (Exception e) {
e.printStackTrace();
}
}
九、重载和重写的区别
重载:在同一个类中,方法名相同,形参列表不同,多个方法构成了重载
重写:在不同的类中,子类对父类提供的方法不满意时,对父类的方法进行重写
项目 | 英文 | 位置 | 修饰符 | 返回值 | 方法名 | 参数 | 抛出异常 | 方法体 |
---|---|---|---|---|---|---|---|---|
重载 | overload | 同一个类中 | 无关 | 无关 | 必须相同 | 必须不同 | 无关 | 不同 |
重写 | override | 子类父类中 | 父类的权限修饰符要低于子类的 | 父类的返回值类型要低于子类的 | 必须相同 | 必须相同 | 子类小于等于父类 | 不同 |
1.重载的异常
public class Demo {
public void a()throws Exception{
}
public void a(int i)throws RuntimeException{
}
2.重写的异常
十、自定义异常
自定义异常可以继承检查时异常也可以继承运行时异常
public class MyException extends RuntimeException{
static final long serialVersionUID = -7034897190745766939L;
public MyException() {
super();
}
public MyException(String message) {
super(message);
}
}