LAPTOP-D55DCTAO_12.16孔鹏曌

12.16

方法可变参数

定义

​ 方法可变参数就是指方法形参的可数可以变化,个数为零或者是n个;

定义方法参数

​ 使用 ... 定义方法可变参数

​ 例:

public double area(int ...param){
}

方法可变参数的规则

  • 一个方法只能有一个可变参数

    下面的例子就是错误的,因为定义了两个可变参数

    public double area(int ...param,int ...aa) {
    }
    
  • 如果一个方法有多个参数,那么可变参数必须定义在最后

    例:

    public void area(int a,int b, int ...c) {
    }
    
  • 方法可变参数本质上是一个数组,因此方法可变参数可以被当做数组来使用

    例:

    public void area(int ...c) {
    if(c!=null && c.length>0) {
    for (int i = 0; i < c.length; i++) {
    System.out.println(c[i]);
    }
    }
    }

方法可变参数的调用

  • 不传入参数

  • 传入多个离散值

  • 传入数组对象

    例:

    Public static void area(int ...c) {
    if(c!=null && c.length>0) {
    for (int i = 0; i < c.length; i++) {
    System.out.println(c[i]);
    }
    }
    }
    public static void main(String[] args) {
    area();//无参调用,此时area()方法的参数c是空指针
    area(1,2,3,4,5);//传入多个离散值,此时area()方法参数c是一个数组,传入的参数是数组元素。
    int score[] = {67,78,56};
    area(score);// 传入数组对象,此时area()法参数c是一个数组。
    }

异常

定义

​ exception(例外),指程序在编译时或者是在运行时发生的不寻常的事情

捕获

​ 发生异常要捕获;

​ 如果一个程序方生异常,那么程序就无法正常运行,会导致程序强行终止运行,当程序发生异常时,我们应该去捕获异常,只要捕获异常,程序中就没有了异常,所以程序就可以正常运行

异常的体系结构

Throwable类

​ Throwable类是异常体系结构的父类,Throwable类的父类是Object类,在Throwable类下分为两套异常类别,分别是Error(错误)和Exception(异常);

Error类

​ Error类是指无法通过开发人员编写程序能够姐居然的异常;

​ 典型的Error:内存溢出、动态链接失败(加载dll文件)、虚拟机错误

Exception类

​ Exception类是所有异常类的父类,这里所指的异常是指能够通过编写程序处理的异常;Exception类有两套子类:运行时异常和编译时异常;

规定:编译时异常必须捕获,如果不捕获会导致程序无法编译

​ 例如ClassnotfoundExcetion就是编译时异常,需要使用try、catch来解决

RuntimeException类

​ RuntimeException类是所有运行时异常的父类

捕获异常

​ 五个捕获异常的关键字:try、catch、finally、throw、throws;

​ 这五个异常关键字分为两类处理异常的方式:try、catch、finally是一组专门处理异常的方式;throw、throws是一组专门处理异常的方式

try、catch、finally异常处理

​ 关键字的使用结构

用法1:
try {
            
} catch (Exception e) {
            
}
用法2:
try {
    
}catch (Exception e) {
    
}finally {
    
}
用法3:
try {
    
} finally{
    
}

​ 解析:

​ 1)try中用于包裹住可能发生异常的代码

​ 2)catch中用于捕获异常,并对异常进行处理

​ 3)finally中用于回收资源

​ 4)try和catch组合时,一个try可以与多个catch组合,但是try只能有一个

​ 5)try与finally组合时,一个try只能与一个finally组合,且try与finally都只能有一个

​ 6)try、catch、finally不能单独使用,catch和finally不能组合使用

示例一:不捕获异常

public class Demo1 {
    public static void main(String[] args) {
        int i=1,j=0,res;
        System.out.println("begin");
        res = i/j;
        System.out.println("end");
    }
}

​ 运行结果:

​ begin

​ Exception in thread "main" java.lang.ArithmeticException: / by zero

​ at homework01.Demo1.main(Demo1.java:6)

​ 分析:

输出begin,没有输出end,说明程序发生异常,也没有捕获,导致程序强行终止运行,提示异常为算术异常,除零异常

示例二:使用try和catch捕获异常

public static void main(String[] args) {
        try {
            int i = 1, j = 0, res;
            System.out.println("begin");
            res = i / j;//抛出异常
            System.out.println("end");
        } catch (Exception e) {//捕获异常
            System.out.println("catched");
            e.printStackTrace();
        }
        System.out.println("over");

​ 运行结果

​ begin

​ catched

​ java.lang.ArithmeticException: / by zero

​ at homework01.Test.main(Test.java:7)

​ over

​ 分析:

​ 1) try中放了可能发生异常的代码

​ 2) 如果try中发生了异常,那么程序就会立即被catch捕获,异常被捕获后异常就没有了,所有程序就可以继续运行。

​ 3) 异常发生后,程序进入到catch,导致从异常发生位置开始到catch位置之间的代码无法运行。

​ 当try中没有发生异常时,程序不会进入到catch中执行

示例3:finally

代码如下

public static void main(String[] args) {
    try {
        int i = 1, j = 0, res;
        System.out.println("begin");
        res = i / j;
        System.out.println("end");
    } catch (ArithmeticException e) {
        System.out.println("catched");
        e.printStackTrace();
    } finally {
        System.out.println("finally");
    }
    System.out.println("over");
}

运行结果

begin

catched

java.lang.ArithmeticException: / by zero

​ at homework01.Test.main(Test.java:7)

finally

over

分析

当try中有finally时,finally是必须要执行的,

如果没有发生异常,执行顺序是try-finally

如果发生了异常,执行顺序是try-catch-finally

示例4:多重catch

​ 代码如下:

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        try {
            System.out.println("计算开始");
            int i, j, res;
            System.out.println("请输入被除数");
            i = input.nextInt();
            System.out.println("请输入除数");
            j = input.nextInt();
            res = i / j;
            System.out.println(i + "/" + j + "=" + res);
            System.out.println("计算结束");
        } catch (InputMismatchException e) {
            System.out.println("除数和被除数必须都是整数");
        } catch (ArithmeticException e) {
            System.out.println("除数不能为零");
        } catch (Exception e) {
            System.out.println("其他异常" + e.getMessage());
        } finally {
            System.out.println("感谢使用本程序");
        }
        System.out.println("程序结束");
    }

​ 分析

一个try可以配置多个catch,但是多个catch是有先后顺序的,必须把子类的catch写在前面,把父类的catch写在后面,并列的catch没有先后顺序。

throw,throws异常处理

​ throw和throws配合是一套处理异常的方式。两者要配合使用。

Throws

​ 用于定义在方法声明的后面,表示该方法可能会抛出异常,并告诉主调方法需要处理该方法抛出的异常。

​ Throws不能单独写一行代码,后面是抛出异常的类型,可抛出多个异常类型,多个之间用逗号分隔。

Throw

​ Throw用在方法内部,后面紧跟一个异常对象,表示要抛出这个异常。

用法1:被调方法不处理异常,直接抛给主调方法

代码如下

    public static void main(String[] args) {
        try {
            divide();
        } catch (ArithmeticException e) {
            e.printStackTrace();
        }
    }
    
    public static void divide() throws ArithmeticException{
        System.out.println("start");
        int i=1,j=0;
        int res = i/j;
        System.out.println("over");
    }

运行结果

start

java.lang.ArithmeticException: / by zero

​ at homework01.Test.divide(Test.java:19)

​ at homework01.Test.main(Test.java:10)

分析

(1) main方法是主调方法

(2) divide是被调方法,被调方法内部发生异常时,被调方法没有处理异常,而是将异常抛给主调方法,由主调方法处理异常。

用法2:被调方法抓住异常后再次抛该主调方法(常用)

​ 需求:将除0的错误描述显示为中文。

​ 代码如下:

    public static void main(String[] args) {
        try {
            divide();
        } catch (ArithmeticException e) {
            e.printStackTrace();
        }
    }
    
    public static void divide() throws
    ArithmeticException{
        try {
            System.out.println("start");
            int i=1,j=0;
            int res = i/j;
            System.out.println("over");
        } catch (Exception e) {
            ArithmeticException ex = ***\*new\**** ArithmeticException("除零异常");
            throw ex;
        }
   }

​ 运行结果

​ start

​ java.lang.ArithmeticException: 除零异常

​ at homework01.Test.divide(Test.java:23)

​ at homework01.Test.main(Test.java:10)

​ 分析:

(1):被调方法先自己处理异常,在抛出异常该主调方法

(2)int res = i/j由于j=\0,jvm抛出ArithmeticException**异常,该异常被catch抓住,所有catch中的e就是i/j时抛出的异常,但是这个异常由于是jvm创建并抛出的,因此是英文提示。

(3)如何改为中文提示。方法是开发人员自定义一个异常对象,在异常对象的构造函数中输入中文异常描述信息,再将这个异常对象使用throw关键字抛出。

​ (4)在主调方法中捕获的异常就是中文信息。

自定义异常

​ Java关于异常提供了很多API,如果这些异常API不能满足你的需要,此时你可以自己定义异常类。用于满足你自己的业务需要。

​ 第一步:定义异常类,继承Exception或者RuntimeException

​ 继承Exception表示自定义编译时异常。

​ 继承RuntimeException表示自定义运行时异常。

​ 第二步:设置异常的描述信息

​ 在Throwable类中定义了描述异常信息的属性,名字是message。可以将自定义异常的描述存储在该属性中。通过构造函数可将异常描述信息传递到throwable中赋值给message属性。

​ 自定义异常示例:

​ 为学生实体对象性别赋值时,只要不是男或者女就是错误的,需要抛出性别异常。

​ 先自定义一个性别异常,命名为GenderException

​ 代码如下

class GenderException extends RuntimeException{
    public GenderException(String message){
        supermessage);
    }

}
class Student{
    private String gender; 
    public String getGender() {
        return gender;
    }
    public void setGender(String gender) {
        if("男".equals(gender) ||"女".equals(gender)) {
            this.gender = gender;
        }
        else {
            throw new GenderException("性别错误,必须是男或女");//抛出异常
        }
    }
}
public class Test {
    public static void main(String[] args) {
        try {
            Student s = new Student();
            s.setGender("公");
        } catch (GenderException e) {
            String message = e.getMessage();
            System.out.println(message);
            e.printStackTrace();
        }
    }
}

异常相关的方法

​ getMesage():获取异常描述信息

​ printStackTrace():输出异常的堆栈信息

标签

评论

© 2021 成都云创动力科技有限公司 蜀ICP备20006351号-1