如何用断言帮助检测错误

Java中的断言通过测试我们认为是正确的代码来帮助检测错误

使用assert关键字进行断言。

其语法为:

assert condition;

这里condition是一个布尔表达式,我们假定在程序执行时为真。

启用断言

默认情况下,断言在运行时被禁用并被忽略。

为了启用断言,我们使用:

java -ea:arguments

或者

java -enableassertions:arguments

启用断言且条件为时true,程序将正常执行。

但是,如果在启用断言时条件计算为false, JVM会抛出AssertionError,程序会立即停止。

示例1:Java 断言

class Main {
  public static void main(String args[]) {
    String[] weekends = {"Friday", "Saturday", "Sunday"};
    assert weekends.length == 2;
    System.out.println("这个星期有 " + weekends.length + " 个周末");
  }
}

输出结果

这个星期有 3 个周末

我们得到上面的输出,因为该程序没有编译错误,并且默认情况下,断言被禁用。

启用断言后,我们得到以下输出:

Exception in thread "main" java.lang.AssertionError

断言的另一种形式声明

assert condition : expression;

在这种形式的断言语句中,将表达式传递到AssertionError对象的构造函数。 如果条件为false,则该表达式的值显示为错误的详细信息。

详细消息用于捕获和传输断言失败的信息,以帮助调试问题。

示例2:带有表达式Java断言示例

class Main {
  public static void main(String args[]) {
    String[] weekends = {"Friday", "Saturday", "Sunday"};
    assert weekends.length==2 : "There are only 2 weekends in a week";
    System.out.println("There are " + weekends.length + "  weekends in a week");
  }
}

输出结果

Exception in thread "main" java.lang.AssertionError:
There are only 2 weekends in a week

从上面的示例可以看出,表达式被传递给AssertionError对象的构造函数。如果我们的假设是正确的false,并且启用了断言,则会抛出异常并显示一条适当的消息。

此消息有助于诊断和修复导致断言失败的错误。

为特定的类和包启用断言

如果我们不向断言命令行开关提供任何参数,

java -ea

这将在除系统类之外的所有类中启用断言。

我们还可以使用参数为特定的类和包启用断言。 可以提供给这些命令行开关的参数为:

在类名中启用断言

为了对程序Main的所有类启用断言,

java -ea Main

只启用一个类,

java -ea:AnimalClass Main

这只允许在Main程序的AnimalClass中使用断言。

在包名称中启用断言

要对包com.animal及其子包启用断言

java -ea:com.animal... Main

在未命名的包中启用断言

在当前工作目录中的未命名包中启用断言(当我们不使用package语句时)。

java -ea:... Main

在系统类中启用断言

为了在系统类中启用断言,我们使用不同的命令行开关:

java -esa:arguments

java -enablesystemassertions:arguments

可以提供给这些开关的参数是相同的。

禁用断言

要禁用断言,我们使用:

java -da arguments

java -disableassertions arguments

要在系统类中禁用断言,我们使用:

java -dsa:arguments

java -disablesystemassertions:arguments

禁用断言时可以传递的参数与启用断言时相同。

断言的优点

  1. 快速高效地检测和纠正错误。

  2. 断言检查仅在开发和测试期间进行。它们会在运行时自动在生产代码中删除,因此不会减慢程序的执行速度。

  3. 它有助于删除样板代码并使代码更具可读性。

  4. 重构和优化代码,以增强其正确运行的信心。

何时使用断言

1.无法访问的代码

无法访问的代码是我们尝试运行该程序时不会执行的代码。使用断言来确保无法访问的代码实际上是无法访问的。

让我们举个实例。

void unreachableCodeMethod() {
  System.out.println("Reachable code");
  return;
  // Unreachable code
  System.out.println("Unreachable code");
  assert false;
}

让我们再来看一个没有默认情况的switch语句示例。

switch (dayOfWeek) {
  case "Sunday":
    System.out.println("It’s Sunday!");
    break;
  case "Monday":
    System.out.println("It’s Monday!");
    break;
  case "Tuesday":
    System.out.println("It’s Tuesday!");
    break;
  case "Wednesday":
    System.out.println("It’s Wednesday!");
    break;
  case "Thursday":
    System.out.println("It’s Thursday!");
    break;
  case "Friday":
    System.out.println("It’s Friday!");
    break;
  case "Saturday":
    System.out.println("It’s Saturday!");
    break;
}

上面的switch语句表明,一周中的天数只能是以上7个值中的一个。没有默认情况意味着程序员相信这些情况中的一个将始终被执行。

但是,在某些假设实际上是错误的情况下,可能尚未考虑某些情况。

应该使用断言来检查此假设,以确保未达到默认switch条件。

default:
    assert false: dayofWeek + " is invalid day";

如果dayOfWeek其值不是有效日期,则抛出AssertionError。

2.记录假设

为了记录其基本假设,许多程序员使用注释。让我们举个实例。

if (i % 2 == 0) {
    ...
} else { // We know (i % 2 == 1)
    ...
}

请改用断言。

随着程序的增长,注释可能会过时和不同步。 但是,我们将不得不更新assert语句; 否则,它们也可能因有效条件而失败。

if (i % 2 == 0) {
   ...
} else {
    assert i % 2 == 1 : i;
    ...
}

什么时候不使用断言

1.公共方法中的参数检查

用户可以提供公共方法中的参数。

因此,如果使用断言来检查这些参数,则条件可能会失败并导致AssertionError。

与其使用断言,不如让它产生适当的运行时异常并处理这些异常。

2.对影响程序操作的表达式求值

不要调用方法或评估可能在断言条件下影响程序操作的异常。

让我们以一个列表示例为例,weekdays列表包含一周中所有天的名称。

ArrayList<String> weekdays = new ArrayList<>(Arrays.asList("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ));

ArrayList<String> weekends= new ArrayList<>(Arrays.asList("Sunday", "Saturday" ));

assert weekdays.removeAll(weekends);

在这里,我们试图从ArrayList weekdays中删除元素Saturday和Sunday。

如果启用了断言,则程序可以正常运行。但是,如果禁用了断言,则不会删除列表中的元素。这可能会导致程序失败。

而是将结果分配给变量,然后使用该变量进行断言。

ArrayList<String> weekdays = new ArrayList<>(Arrays.asList("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ));

ArrayList<String> weekends= new ArrayList<>(Arrays.asList("Sunday", "Saturday" ));

boolean weekendsRemoved = weekdays.removeAll(weekends);
assert weekendsRemoved;

这样,我们可以确保从weekdays中删除所有weekends,而不考虑启用或禁用断言。 结果,它不会影响将来的程序操作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/57089.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

PHP语言基础知识(超详细)

文章目录 前言第一章 PHP语言学习介绍 1.1 PHP部署安装环境1.2 PHP代码工具选择 第二章 PHP代码基本语法 2.1 PHP函数知识介绍2.2 PHP常量变量介绍 2.2.1 PHP变量知识&#xff1a;2.2.2 PHP常量知识&#xff1a; 2.3 PHP注释信息介绍2.4 PHP数据类型介绍 2.4.1 整形数据类型2.4…

Vault数据备份恢复-MySQL

前言 Vault提供了可靠的功能来保护数据库和其他关键数据。 对于MySQL数据库,Vault提供了一个易于使用的解决方案,可以自动创建和管理定期备份,并支持从备份中快速恢复数据。本文将介绍Vault后端存储MySQL的备份恢复,包括如何设置Vault、如何进行数据备份和还原、如何保护…

day49-Springboot

Springboot 1. Springboot简介 1.1 简介&#xff1a;Springboot来简化Spring应用开发的一个框架&#xff0c;约定大于配置 1.2 优点&#xff1a; 可以快速的构建独立运行的Spring项目&#xff1b; 框架内有Servlet容器&#xff0c;无需依赖外部&#xff0c;所以不需要达成w…

二十三种设计模式第二十四篇--访问者模式(完结撒花)

在访问者模式&#xff08;Visitor Pattern&#xff09;中&#xff0c;我们使用了一个访问者类&#xff0c;它改变了元素类的执行算法。 通过这种方式&#xff0c;元素的执行算法可以随着访问者改变而改变。 这种类型的设计模式属于行为型模式。根据模式&#xff0c;元素对象已接…

如何监控制造业精密空调?看这技能就够了!

在半导体制造、电子元件生产、光学设备制造等领域&#xff0c;精密空调监控是关键的保障&#xff0c;因为微小的温度或湿度变化、微生物或颗粒物污染都可能对产品质量和性能造成巨大影响。 精密空调监控系统作为一种高度智能化的解决方案&#xff0c;能够实时监测和调节生产环境…

SQL注入之sqlmap

SQL注入之sqlmap 6.1 SQL注入之sqlmap安装 sqlmap简介&#xff1a; sqlmap是一个自动化的SQL注入工具&#xff0c;其主要功能是扫描&#xff0c;发现并利用给定的URL的SQL注入漏洞&#xff0c;目前支持的数据库是MS-SQL,MYSQL,ORACLE和POSTGRESQL。SQLMAP采用四种独特的SQL注…

新手入门Jenkins自动化部署入门详细教程

1. 背景 在实际开发中&#xff0c;我们经常要一边开发一边测试&#xff0c;当然这里说的测试并不是程序员对自己代码的单元测试&#xff0c;而是同组程序员将代码提交后&#xff0c;由测试人员测试&#xff1b; 或者前后端分离后&#xff0c;经常会修改接口&#xff0c;然后重新…

【Python】Python 实现猜单词游戏——挑战你的智力和运气!

文章目录 前言学到什么?导入 random 模块定义生命次数定义神秘单词并进行随机选择定义 clue&#xff08;猜测进度&#xff09; 列表&#xff0c;用问号 ? 初始化定义心形符号的 Unicode 编码初始化 guessed_word_correctly 变量定义更新猜测进度函数 update_clue主循环&#…

使用上 Spring 的事件机制

本文主要是简单的讲述了Spring的事件机制&#xff0c;基本概念&#xff0c;讲述了事件机制的三要素事件、事件发布、事件监听器。如何实现一个事件机制&#xff0c;应用的场景&#xff0c;搭配Async注解实现异步的操作等等。希望对大家有所帮助。 Spring的事件机制的基本概念 …

邪恶版ChatGPT来了!

「邪恶版」ChatGPT 出现&#xff1a;每月 60 欧元&#xff0c;毫无道德限制&#xff0c;专为“网络罪犯”而生。 WormGPT 并不是一个人工智能聊天机器人&#xff0c;它的开发目的不是为了有趣地提供无脊椎动物的人工智能帮助&#xff0c;就像专注于猫科动物的CatGPT一样。相反&…

Ansible —— playbook 剧本

Ansible —— playbook 剧本 一、playbook的概述1.playbook简介2.什么是Ansible playbook剧本&#xff1f;3.Ansible playbook剧本的特点4.如何使用Ansible playbook剧本&#xff1f;5.playbooks 本身由以下各部分组成 二、playbook示例1.运行playbook2.定义、引用变量3.指定远…

JAVA 反编译工具

Releases deathmarine/Luyten GitHub 安装exe 打开拖入文件即可

九耶|阁瑞钛伦特:产品经理面试题—产品经理在工作中是如何划分需求优先级的?

产品经理在工作中划分需求优先级是为了指导产品团队的开发和发布流程。以下是产品经理在划分需求优先级时通常考虑的因素&#xff1a; 业务目标&#xff1a;产品经理会与企业领导层或业务方合作&#xff0c;了解公司的战略目标和销售策略。然后&#xff0c;他们会根据这些目标评…

图像 检测 - YOLOv3: An Incremental Improvement (arXiv 2018)

YOLOv3: An Incremental Improvement - 增量改进&#xff08;arXiv 2018&#xff09; 摘要1. 引言2. 处理2.1 边界框预测2.2 类别预测2.3 跨规模预测2.4 特征提取器2.5 训练 3. 我们的做法4. 我们尝试过但没有成功的事情5. 这一切意味着什么References 声明&#xff1a;此翻译仅…

Netty:从ByteBuf中读出数据

介绍 Netty的ByteBuf数据位置索引是0开始的。 可以用ByteBuf的getByte(int index)方法从指定位置读出一字节&#xff0c;这个操作不会改变ByteBuf的readerIndex 或者 writerIndex 的位置。如果index小于0&#xff0c;或者index 1大于ByteBuf的容量&#xff0c;就会抛出IndexO…

下载列表视频的具体操作

主要是介绍怎样获取上篇博客需要的HAR文件和请求域名

Vulnhub靶机DC-2 writeup

靶机介绍 靶机介绍&#xff1a;https : //download.vulnhub.com/dc/DC-2.zip ​ 信息搜集 获取IP地址 扫描靶机的IP的方法 1. nmap -sP 192.168.142.0/24 #nmap进行ping扫描发现存活主机 2. arp-scan -l #基于ARP发现内网存活主机 3. netdiscover -r 192.168.142.0/24 -…

Java导出数据到Excel

Java导出数据到Excel分3步处理 1、构建Workbook 数据 2、设置Workbook 格式 3、导出到Excel 1、构建Workbook 数据 public static void buildData(Workbook wb, List<Person> list) {Sheet sheetName wb.createSheet("sheetName");Row row sheetName.creat…

Java 中的 7 种重试机制

随着互联网的发展项目中的业务功能越来越复杂&#xff0c;有一些基础服务我们不可避免的会去调用一些第三方的接口或者公司内其他项目中提供的服务&#xff0c;但是远程服务的健壮性和网络稳定性都是不可控因素。 在测试阶段可能没有什么异常情况&#xff0c;但上线后可能会出…

C++---list常用接口和模拟实现

list---模拟实现 list的简介list函数的使用构造函数迭代器的使用list的capacitylist element accesslist modifiers list的模拟实现构造函数&#xff0c;拷贝构造函数和迭代器begin和endinsert和eraseclear和析构函数 源码 list的简介 list是用双向带头联表实现的一个容器&…