当前位置: 首页 > news >正文

第四章 异常处理

1. 异常:认识异常

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

2. 异常:自定义异常、异常的作用

在这里插入图片描述

年龄非法异常类(运行时异常):

package com.itheima.exception;

/**
 * @ClassName AgeIllegalRuntimeException
 * @Description 年龄非法运行时异常
 * @Author 孙克旭
 * @Date 2025/3/25 18:50
 */
public class AgeIllegalRuntimeException extends RuntimeException {
    public AgeIllegalRuntimeException() {
    }

    public AgeIllegalRuntimeException(String message) {
        super(message);
    }
}

年龄非法异常类(编译时异常):

package com.itheima.exception;

/**
 * @ClassName AgeIllegalException
 * @Description 年龄非法编译时异常
 * @Author 孙克旭
 * @Date 2025/3/25 18:50
 */
public class AgeIllegalException extends Exception {
    public AgeIllegalException() {
    }

    public AgeIllegalException(String message) {
        super(message);
    }
}

测试类:

package com.itheima.exception;

public class Demo1 {
    public static void main(String[] args) {
        try {
            saveAge(160);
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            saveAge2(160);
        } catch (AgeIllegalException e) {
            e.printStackTrace();
        }
    }

    /**
     * 保存年龄
     *
     * @param i
     */
    private static void saveAge(int i) {
        if (i >= 0 && i <= 150) {
            System.out.println("年龄保存成功!");
        } else { //抛出异常
            throw new AgeIllegalRuntimeException("/age is illegal:" + i);
        }
    }


    private static void saveAge2(int i) throws AgeIllegalException {
        if (i >= 0 && i <= 150) {
            System.out.println("年龄保存成功!");
        } else { //抛出异常
            throw new AgeIllegalException("/age is illegal:" + i);
        }
    }
}

3. 异常:异常的常见处理方式一

在这里插入图片描述

在这里插入图片描述

4. 异常:异常的常见处理方式二

在这里插入图片描述

5. 课后练习

5.1 问题1

  1. 请描述异常的继承体系
  2. 请描述你对错误(Error)的理解
  3. 请描述你对异常(Expection的理解)
  4. 请描述你对运行时异常(RuntimeException)的理解

1.    异常继承体系为:异常的根类是 java.lang.Throwable,其下有两个子类:
java.lang.Errorjava.util.Exception 。而Exception又分为编译时期异常:checked异常,与运行时期异常:runtime异常。
2.    Error:表示不可修复的恶性的错误,只能通过修改代码规避错误的产生,通常是系统级别的,所以很严重。
3.    Exception:表示可修复的良性(相对于错误)的异常,异常产生后程序员可以并且应该通过代码的方式纠正,使程序继续运行,是必须要处理的。
4.    运行时期异常:runtime异常。在运行时期,检查异常.在编译时期,运行异常不会编译器检测(不报错)

5.2 问题2

  1. 请描述throw的使用位置,作用是什么?
  2. 请描述throws的使用位置,作用是什么?

1.    throw关键字通常用在方法体中,并且抛出一个异常对象。程序在执行到throw语句时立即停止,它后面的语句都不执行。
2.    throws关键字通常被应用在声明方法时,用来指定可能抛出的异常。多个异常可以使用逗号隔开。当在主函数中调用该方法时,如果发生异常,就会将异常对象抛给方法调用处。

5.3 问题3

  1. 异常处理方式有几种,分别是什么?
  2. 详细阐述每种方式对异常是如何处理的


1.    异常的处理方式有两种,分别是使用throwstry...catch
2.    throws用在方法的声明上后接异常类名,是把异常抛给调用者进行处理
3.    try...catch是捕获异常,自己处理,处理完毕后面的程序可以继续运行
a)    try代码块中是可能出现异常的代码
b)    catch代码块,是遇到异常,对异常进行处理的代码

5.4 问题4

请列举常见异常,并说明产生原因



NullPointerException:空指针异常。
    当应用试图在要求使用对象的地方使用了null时,抛出该异常。譬如:调用null对象的实例方法、访问null对象的属性、计算null对象的长度等等。
ArrayIndexOutOfBoundsException:数组索引越界异常。
当对数组的索引值为负数或大于等于数组大小时抛出此异常。
ArithmeticException:算术运算异常。
    程序中出现了除以零这样的运算就会出这样的异常,对这种异常,大家就要好好检查一下自己程序中涉及到数学运算的地方,公式是不是有不妥了。
NumberFormatException:数字格式异常。
    当试图将一个String转换为指定的数字类型,而该字符串确不满足数字类型要求的格式时,抛出该异常。

5.5 问题5

根据给出的相应代码,分析可能产生的结果。

1.举例:
public static void main(String[]args){

String str=null;
System.out.println(str.length());

}

2.举例:
public static void main(String[]args){
int arr[]={1,2};
System.out.println(arr[2]);
}

3.举例:
public static void main(String[]args){

System.out.println(1/0);
}

4.举例:
public static void main(String[]args){

System.out.println(Integer.parseInt(“itcast”));

}

5.举例:
public static void main(String[] args) {
SimpleDateFormat format = new SimpleDateFormat(“yyyy-MM-dd”);

try {
    Date date = format.parse("2018-04-03");
    System.out.println("程序正常");

} catch (ParseException e) {
    System.out.println("程序异常");
}

}


结合代码:1.举例:

public static void main(String[]args){

?String str=null;
System.out.println(str.length());

}
答:变量str的值为null,调用方法时,报空指针异常NullPointerException

2.举例:

public static void main(String[]args){
int arr[]={1,2};
System.out.println(arr[2]);
}
答:索引值2大于等于数组arr的长度时,报数组索引越界异常ArrayIndexOutOfBoundsException

 

3.举例:

public static void main(String[]args){

System.out.println(1/0);
}
答:整数0做了分母,报算术运算异常ArithmeticException:/by zero

4.举例:

public static void main(String[]args){

System.out.println(Integer.parseInt("itcast"));

}
答:把字符串“itcast”转换为Integer类型时,当然会报数字格式化异常啦NumberFormatException

 

5.举例:

    public static void main(String[] args){
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        try {
            Date date = format.parse("2018-04-03");
            System.out.println("程序正常");

        } catch (ParseException e) {
            System.out.println("程序异常");
        }
    }
答: 打印结果“程序正常”.try代码块中并没有产生异常,catch代码块中的代码不会执行。date为201813000400秒。

5.6 问题6

请使用代码实现
每一个学生(Student)都有学号,姓名和分数,分数永远不能为负数
如果老师给学生赋值一个负数,抛出一个自定异常


 1.定义异常类NoScoreException,继承RuntimeException

a)提供空参和有参构造方法

 

public class NoScoreException extends RuntimeException {
//  空参构造
public NoScoreException() {
super();
 }
// 有参构造
public NoScoreException(String message) {
super(message);
 }
}
 

  2.定义学生类(Student)

 a)属性:name,score

 b)提供空参构造

 c)提供有参构造;

  i.使用setXxx方法给名称和score赋值

 d)提供setter和getter方法

  i.setScore(int score)方法中

   1.首先判断,如果score为负数,就抛出NoScoreException,异常信息为:分数不能为负数:xxx.

   2.然后在给成员score赋值.

public class Student {
private String name;
private int score;
// 空参构造
public Student() {
super();
 }
// c)提供有参构造;
// i.使用setXxx方法给名称和score赋值
public Student(String name,int score){
  setName(name);
  setScore(score);
 }
// d)提供setter和getter方法

public String getName() {
return name;
 }

public void setName(String name) {
this.name = name;
 }

public int getScore() {
return score;
 }
// i.在setScore(int score)方法中
public void setScore(int score) {
// 1.首先判断,如果score为负数,就抛出NoScoreException,异常信息为:分数不能为负数:xxx.
if(score <0){
throw new NoScoreException(":分数不能为负数:"+score);
  }
// 2.然后在给成员score赋值.
this.score = score;
 }
}
3.定义测试类Test9

 a)提供main方法,在main方法中

  i.使用满参构造方法创建Student对象,分数传入一个负数,运行程序

  ii.由于一旦遇到异常,后面的代码的将不在执行,所以需要注释掉上面的代码

  iii.使用空参构造创建Student对象

  iv.调用setScore(int score)方法,传入一个正数,运行程序

  v.调用setScore(int score)方法,传入一个负数,运行程序

public class Test9 {
public static void main(String[] args) {
//  i.使用满参构造方法创建Student对象,分数传入一个负数,运行程序
//  Student s = new Student("景甜", -10);
//  ii.由于一旦遇到异常,后面的代码的将不在执行,所以需要注释掉上面的代码

//  iii.使用空参构造创建Student对象
Student s = new Student();
//  iv.调用setScore(int score)方法,传入一个正数,运行程序
s.setScore(100);
//  v.调用setScore(int score)方法,传入一个负数,运行程序
s.setScore(-5);
 }
}

6. 单元练习14

6.1 什么是异常?

程序在运行过程中发生的意外情况,称为异常,如:除数为0、访问下标不存在的数组元素等
异常是一种信号,用于向调用者传递信息,表示程序发生了意外情况
程序运行时一旦出现了异常,将会导致程序立即终止,异常之后的代码将无法继续执行,所以需要对异常进行处理。

6.2 异常的作用是什么?

保证程序的稳定性和健壮性。异常是程序运行过程中的常态,可以及时发现并处理这些问题,防止程序崩溃或出现其他严重的后果。
提高代码的可读性和可维护性。通过异常的处理机制,可以将错误信息以更容易理解和维护的方式呈现给开发者,有利于代码的修改和优化。
提高程序的可靠性。异常可以被用来判断程序是否正常运行,以及记录程序中的错误信息,从而提高程序的可靠性和稳定性。
促进代码的重用和复用。通过捕获和处理异常,可以将程序中的错误信息和处理逻辑封装成一个独立的模块,方便其他代码重用和复用。

6.3 简述throw和throws的区别?

throw用在方法内部,后面跟一个异常对象,用来抛出一个异常
② throws用在方法定义上,后面跟一个异常类型,用来给方法添加一个异常声明。告诉方法的调用者,该方法可能会出现异常。

6.4 编码题1

在一个程序中有1,2,3三个选项交给用户选择,用户输入其他选项时会给出友好提示,请设计一个程序模拟该过程
1.在测试类中,使用键盘录入让用户输入选项1,2,3,通过if语句判断分别给出提示:选项一;选项二;选项三;
2.若用户输入其他内容时抛出运行时异常,信息为:输入有误


public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);
        System.out.println("请输入你的选项:1 or 2 or 3");
        String next = sc.next();

        if (!(List.of("1", "2", "3").contains(next)))
         throw new RuntimeException("你输入的选项有误。请重新输入");
        if ("1".equals(next))
            System.out.println("选项一");
        if ("2".equals(next))
            System.out.println("选项二");
        if ("3".equals(next))
            System.out.println("选项三");
    }

6.5 编码题2

现在老师要统计学生信息,已知该班学生年龄在18-25之间,如果不在范围内,则输入错误,请编写代码模拟该过程
①创建一个学生类(name,age),对学生的年龄赋值进行限制,如果输入的学生年龄不在范围内,则抛出异常
②在测试类中完成创建学生对象,并对学生对象进行赋值,对学生的年龄输入一个非法数值,查看控制台输出


public class Student {
    private String name;
    private int age;

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if(age >= 18 && age <= 25){
            this.age = age;
        }else{
            //当年龄不合法时,产生一个异常
            throw new RuntimeException("年龄超出了范围");
        }
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

6.6 编码题3

设计一个程序模拟计算机计算两个整数乘积的过程
①通过键盘录入让用户输入两个整数,如果用户输入的不是整数,则提示用户重新输入
②计算两个数的乘积,并将结果打印在控制台
(已知:如果我们使用nextInt方法让用户输入整数,但用户实际输入的不是整数的时候,会发生异常,而对于一个键盘输入对象来说,一旦发生异常,即使使用try{}catch(){}语句进行了处理,这个键盘输入对象也无法继续工作了,解决的办法就是重写创建新的键盘输入对象即可;)


public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int i = 1;
        int a, b;
        while (true) {
            try {
                System.out.println("请输入第" + i + "个整数");
                a = sc.nextInt();
                i++;
                break;
            } catch (Exception e) {
                System.out.println("输入有误,请务必输入整数!");
                sc = new Scanner(System.in);
            }
        }
        while (true) {
            try {
                System.out.println("请输入第" + i + "个整数");
                b = sc.nextInt();
                i++;
                break;
            } catch (Exception e) {
                System.out.println("输入有误,请务必输入整数!");
                sc = new Scanner(System.in);
            }
        }
        int c = a * b;
        System.out.println(a + "乘以" + b + "=" + c);
    }

7. 章节测评-异常处理

7.1 Calendar类的作用是什么?它的常用方法有哪些?

Calendar类是Java中用于表示日期和时间的抽象类,它提供了一些方法来操作日期和时间。
Calendar类的常用方法包括以下几种:

getInstance():获取当前日历对象
get(int field):获取日历中的某个信息,例如获取年、月、日等
set(int field, int value):修改日历的某个信息,例如设置年、月、日等
add(int field, int amount):为某个信息增加/减少指定的值,例如将年加1、月减2getTimeInMillis():返回一个表示Calendar对象所表示时间的Date对象
getTime():获取日期对象

7.2 简述throw和throws的区别?

throw用在方法内部,后面跟一个异常对象,用来抛出一个异常
② throws用在方法定义上,后面跟一个异常类型,用来给方法添加一个异常声明。告诉方法的调用者,该方法可能会出现异常。

7.3 Lambda表达式省略规则?

①在标准格式的基础上()中的参数类型可以直接省略
②如果{}总的语句只有一条语句,则{}可以省略、return关键字、以及最后的“;”都可以省略
③如果()里面只有一个参数,则()可以省略

7.4 编码题1

给一家超市管理系统编写一个程序
1.要求能够统计每种商品销售量的前N名,并输出其销售数量及商品名称
2.商品信息存储在一个数组中,每个元素包含商品名称和销售数量两个属性。
3.编写一个方法,能够接收一个商品信息数组和一个整数N,返回销售量前N名的商品信息。
提示:可以使用Arrays类的sort方法进行排序,使用Comparator接口自定义排序规则,然后使用Arrays类的copyOf方法进行结果拷贝


public class AppTest {
    public static void main(String[] args)  {
        //1,准备商品信息数组
        Product[] products = {
                new Product("苹果", 1000),
                new Product("香蕉", 800),
                new Product("橙子", 925),
                new Product("草莓", 1026),
                new Product("西瓜", 765),
        };
        // 2,定义 N
        int N = 3;

        // 3,统计销售量排名前 N 的商品信息
        Product[] p = topNProducts(products,N);
        System.out.println(Arrays.toString(p));
    }

    private static Product[] topNProducts(Product[] products, int n) {
        Arrays.sort(products, new Comparator<Product>() {
            @Override
            public int compare(Product o1, Product o2) {
                return Integer.compare(o2.getSales(),o1.getSales());
            }
        });

        if (n >= products.length) {
            return products;
        }
        return Arrays.copyOf(products,n);
    }
}
public class Product {
    private String name;//商品名称
    private int sales;//销售数量

    public Product(String name, int sales) {
        this.name = name;
        this.sales = sales;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getSales() {
        return sales;
    }

    public void setSales(int sales) {
        this.sales = sales;
    }

    @Override
    public String toString() {
        return "Product{" +
                "name='" + name + '\'' +
                ", sales=" + sales +
                '}';
    }
}

7.5 编码题2

设计一个成绩管理系统,
①该系统使用数组记录多个学生的成绩信息
②编写学生对象包含姓名、语文、数学、英语成绩,和查询总分的方法
③编写测试类实现查询学生排名等功能。要求使用Lambda表达式
⑥编写CompareByData类,在里面定义比较方法,使用实例方法引用简化lambda表达式。


import java.util.Arrays;

public class StudentRanking {
public static void main(String[] args) {
Student[] students = new Student[]{
new Student("张三", 90, 80, 70),
new Student("李四", 80, 70, 60),
new Student("王五", 70, 60, 50),
new Student("赵六", 60, 50, 40),
new Student("钱七", 50, 40, 30)
};

// 计算每个学生的总成绩,并排序输出
Arrays.sort(students, (s1, s2) -> s2.getTotalScore() - s1.getTotalScore());
System.out.println("lambda方式:");
for (int i = 0; i < students.length; i++) {
Student student = students[i];
System.out.println("第"+(i+1)+"名:"+ student.getName()+",总成绩:"+student.getTotalScore());
}
CompareByData compareByData = new CompareByData();
Arrays.sort(students, compareByData::compareByTotalScore);
System.out.println("实例方法引用方式:");
for (int i = 0; i < students.length; i++) {
Student student = students[i];
System.out.println("第"+(i+1)+"名:"+ student.getName()+",总成绩:"+student.getTotalScore());
}
}
}
public class CompareByData {

public  int compareByTotalScore(Student s1, Student s2) {
return s2.getTotalScore() - s1.getTotalScore();
}
}
public class Student {
private String name;
private int mathScore;
private int englishScore;
private int chineseScore;

public Student(String name, int mathScore, int englishScore, int chineseScore) {
this.name = name;
this.mathScore = mathScore;
this.englishScore = englishScore;
this.chineseScore = chineseScore;
}

public String getName() {
return name;
}

public int getTotalScore() {
return mathScore + englishScore + chineseScore;
}
}

7.6 编码题3

设计一个程序模拟计算机计算两个整数乘积的过程
①通过键盘录入让用户输入两个整数,如果用户输入的不是整数,则提示用户重新输入
②计算两个数的乘积,并将结果打印在控制台
(已知:如果我们使用nextInt方法让用户输入整数,但用户实际输入的不是整数的时候,会发生异常,而对于一个键盘输入对象来说,一旦发生异常,即使使用try{}catch(){}语句进行了处理,这个键盘输入对象也无法继续工作了,解决的办法就是重写创建新的键盘输入对象即可;)


  public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int i = 1;
        int a, b;
        while (true) {
            try {
                System.out.println("请输入第" + i + "个整数");
                a = sc.nextInt();
                i++;
                break;
            } catch (Exception e) {
                System.out.println("输入有误,请务必输入整数!");
                sc = new Scanner(System.in);
            }
        }
        while (true) {
            try {
                System.out.println("请输入第" + i + "个整数");
                b = sc.nextInt();
                i++;
                break;
            } catch (Exception e) {
                System.out.println("输入有误,请务必输入整数!");
                sc = new Scanner(System.in);
            }
        }
        int c = a * b;
        System.out.println(a + "乘以" + b + "=" + c);
    }

相关文章:

  • 基于大模型的结核性胸膜炎风险预测及临床方案研究报告
  • CF2041C Cube
  • 《Operating System Concepts》阅读笔记:p481-p482
  • stanley 路径跟踪控制算法
  • 从概率到梯度:理解分类问题中交叉熵的优越性
  • 竞品已占据市场先机,如何找到差异化突破口
  • IT监控知识库:构建智能运维的认知中枢
  • idea激活后一直出现弹窗解决办法
  • 银行分布式新核心的部署架构(两地三中心)
  • 【实战ES】实战 Elasticsearch:快速上手与深度实践-2.2.1 Bulk API的正确使用与错误处理
  • 小爱控制OK影视搜索视频
  • 《Python实战进阶》第33集:PyTorch 入门-动态计算图的优势
  • 正学传承人——理行
  • Langchain RAG介绍和最佳实践
  • 突破反爬困境——SDK架构设计,为什么选择独立服务模式(四)
  • Qt中10倍提升动态截屏及渲染60帧/秒
  • 【江协科技STM32】BKP备寄存器RTC实时时钟(学习笔记)
  • 对三维物体模型的阈值操作
  • C++设计模式-桥梁模式:从基本介绍,内部原理、应用场景、使用方法,常见问题和解决方案进行深度解析
  • 08_JavaScript数据操作方法_数组
  • 定西市网站建设咨询/杭州网站建设方案优化
  • 网站程序是如何开发的/建立自己的网站平台
  • 建设网站分几个步骤/短视频推广渠道有哪些
  • 网站pc端和手机端分离怎么做/排名公式
  • 南昌企业制作网站设计/百度手机卫士
  • 旅游网站制作建设/广告联盟推广