异常

1.try

异常被捕获后,可以继续执行后续代码,如果未捕获,就不再执行后续代码

try: 尝试

将可能出现异常的代码放入try块中,不要将过多的代码放进try中。=,没有阅读性。

使用要求:try不能单独出现,必须结合catch或者finally或者catch-finally

情景:1.出现的异常和捕获的异常是匹配的,捕获异常,程序继续执行,不中断

2.出现的异常和捕获的异常是不匹配的,不会捕获,程序中断,不再执行

3.捕获多个异常,多个异常写多个catch块,捕获子类和父类异常时,先写子类,后写父类。

4.捕获多个异常时,我们可以统一捕获一个父类 Exception。但实际开发中不建议这样使用,因为没有阅读性可言。

Throwable两大子类: Error Exception

Exception两种子类:

1.运行时异常(RuntimException),可处理可不处理

2.检查(编译时)异常,必须处理

2.catch

catch:捕获

使用要求:不能单独出现,必须结合try

表示捕获到异常后将执行的处理代码

多个异常写多个catch块,捕获子类和父类异常时,先写子类,后写父类

3.finally

finally:最终

不管是否出现异常都执行的代码块,或者异常是否匹配到都会执行

使用要求:不能单独出现必须结合try,或者try-catch

适用场景:通常用于关闭资源或者一些必须执行的操作

finally不执行的唯一情况,退出JVM虚拟机·

System.exit(int status);

status:0表示正常退出,非0表示非正常退出,虽然表示的含义不同,但执行退出虚拟机的效果是一样的(只是为了区分jvm关闭原因)

import java.util.Scanner;

/**
 *  finally关键字  最终
 *  注意:不能单独出现 必须结合 try-catch 或者结合try
 *  finally中的代码 表示不管是否出现异常都执行 或者 异常是否被捕获到都执行
 *  应用场景:当我们需要关闭一些资源的时候  
 * @author asus
 *
 */
public class Test1 {
    public static void main(String[] args) {
        try {
            Scanner in = new Scanner(System.in);
            System.out.print("请输入被除数:");
            int num1 = in.nextInt();
            System.out.print("请输入除数:");
            int num2 = in.nextInt();
            System.out.println(num1+"/"+ num2 +"="+ num1/ num2);
            
        }catch(ArithmeticException e) {
                e.printStackTrace();
        }finally {
            System.out.println("感谢使用本程序!");
        }
        
    }
}

4.throws

throws:抛的复数

使用throws声明当前方法有可能出现的异常给调用者

使用位置:在方法形参列表小括号之后

使用方式:可声明多个异常,使用逗号隔开

调用者处理异常的两种情况:

运行时异常(RuntimeException),那么调用者可处理也可不处理,编译也不会报错

检查异常(CheckedException) 那么调用者必须处理

检查异常处理有如下两种方式:

  1.继续声明给JVM虚拟机,自己不做处理

  2.加上try-catch自行处理

5.throw

throw:抛

位置:方法体内部 可作为一条单独的语句,一条语句只能抛出一个异常

 

throw

throws

生成并抛出异常

声明方法内抛出了异常

位于方法体内部,可作为单独语句使用

必须跟在方法参数列表后面,不能单独使用

抛出一个异常对象,且只能是一个

声明抛出异常类型,可以跟多个异常

6.自定义异常

当JDK提供的异常不能满足我们的开发时,我们可以自定义异常来实现需求

1.先编写异常类

2.继承父类(Exception、Throwable、RuntimeException)都可以

3.编写构造方法,传入异常信息

4.在代码中抛出自定义异常

public class AgeException extends Exception{

    private static final long serialVersionUID = 1L; // 序列化ID 自动生成

    public AgeException(String message) {
        super(message);
    }
}
public class SexException extends RuntimeException{

    private static final long serialVersionUID = 1L;
    public SexException(String message) {
        super(message);
    }
}
public class Person {
    private String name;
    private int age;
    private String sex;
    public int getAge() {
        return age;
    }
    public void setAge(int age) throws AgeException {
        if(age > 0 && age <= 130) {
            this.age = age;
        }else {
            throw new AgeException("年龄不合适");
        }
    }
    
    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        if(sex.equals("男") || sex.equals("女")) {
            this.sex = sex;
        }else {
            throw new SexException("性别不合适");
        }
    }
    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    
    public static void main(String[] args) {
        Person p1 = new Person();
        try {
            p1.setAge(111);
        } catch (AgeException e) {
            e.printStackTrace();
        }
        p1.setSex("男");
    }
}

面试题:try-catch块中存在return语句,是否还执行finally块? 如果执行,说出执行顺序

详细链接: 

try语句在返回前,将其他所有的操作执行完(未考虑try出现异常的情况,出现异常时执行catch,规则与其相同),保留好要返回的值,而后转入执行finally中的语句,而后分为以下三种情况:

情况一:如果finally中有return语句,则会将try中的return语句"覆盖"掉(异常在返回值之前除外,此时不执行try中的return语句),直接执行finally中的return语句,得到返回值,这样便无法的得到try之前保留好的返回值

情况二:如果finally中没有return语句,也没有改变要返回的值,则执行完finally中的语句后,会接着执行try中的return语句,返回之前保留的值

情况三如果finally中没有return语句,但是改变了要返回的值,这里优点类似于引用传递和值传递的区别,分以下两种情况:

        a)如果return的数据是基本数据类型或文本字符串,则在finally中对该基本数据的改变不起作用,try中的return语句依然会返回进入finally块之前保留的值

        b)如果return的数据类型是引用数据类型,而在finally中对该引用数据类型的属性值的改变起作用,try中的return语句返回的值就是在finally中改变后的该属性的值。

补充:出现异常捕获时,执行catch语句,其规则与try中相同。

任何执行try 或者catch中的return语句之前,都会先执行finally语句

 每日问题

1.异常的体系结构,写出三个父类

2.try-catch-finally-throw-throws关键字分别用途是什么?

3.RunTimeException和CheckedException有在处理上有什么不同?

4.try-catch-finally中 如果try中已经return了值 那么finally中对返回值的操作会不会改变返 回值?

5.finally不执行的唯一情况是什么?

6.继承中实现多态的主要方式是什么?两种

7.throw和throws的区别

8.自定义异常的步骤

9.静态方法中如何访问实例属性和方法?

10.java支持多继承吗?

解答

1.异常的体系结构,写出三个父类

     Throwable Exception Error

2.try-catch-finally-throw-throws关键字分别用途是什么?

    try 可能出现异常的代码

    catch 捕获异常

    finally 不管是否出现异常都将执行的代码

    throw 抛出一个异常

    throws 声明异常,可以声明多个

3.RunTimeException和CheckedException有在处理上有什么不同?

    RuntimeException 不是必须处理

    CheckedException 必须处理 继续声明给JVM虚拟机 或者 try-catch处理

4.try-catch-finally中 如果try中已经return了值 那么finally中对返回值的操作会不会改变返 回值?

5.finally不执行的唯一情况是什么?

    System.exit(int status); status 为0表示正常退出 非0 表示非正常退出 效果都一样

6.继承中实现多态的主要方式是什么?两种

    父类作为形参 父类作为返回值

7.throw和throws的区别

    throw是在方法体内部单独作为一条语句使用 抛出异常

    throws声明异常,写在形参列表之后 可以声明多个 多个之间逗号隔开

8.自定义异常的步骤

    编写异常类

    继承父类(Throwable,Exception,RuntimeException)

    编写构造方法 方法中抛出自定义异常

9.静态方法中如何访问实例属性和方法? 不能,必须先new对象,然后通过对象名. 访问

10.java支持多继承吗? 不支持,但是可以通过接口继承接口的方式实现类似多继承的效果