如何用断言帮助检测错误

news2024/12/25 12:15:28

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,而不考虑启用或禁用断言。 结果,它不会影响将来的程序操作。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

手把手教你从零开始搭建个人博客

随着技术的进步和用户需求的变化&#xff0c;个人博客的形式和内容一直在不停地演变。为了给读者提供更丰富、有趣的阅读体验&#xff0c;搭建个人博客的网站一直在寻找更好的优化方法。所以现在出现了一批功能更完善的个人博客搭建软件&#xff0c;今天looklook就以HelpLook为…

【css】样式 +GASP

纯CSS实现四种方式文本反差色效果 mix-blend-mode: difference; clip-path&#xff1b; background-clip: text, padding-box outline 是绘制于元素周围的一条线&#xff0c;位于边框边缘的外围&#xff0c;可起到突出元素的作用。 css 样式之 filter 滤镜属性 用法与示例 使…

java版直播商城平台规划及常见的营销模式+电商源码+小程序+三级分销+二次开发 bbc

&#xfeff; 1. 涉及平台 平台管理、商家端&#xff08;PC端、手机端&#xff09;、买家平台&#xff08;H5/公众号、小程序、APP端&#xff08;IOS/Android&#xff09;、微服务平台&#xff08;业务服务&#xff09; 2. 核心架构 Spring Cloud、Spring Boot、Mybatis、R…

java实现面板之间切换功能

本文实例为大家分享了java实现面板之间切换的具体代码&#xff0c;供大家参考&#xff0c;具体内容如下 如图&#xff1a; 关键技术&#xff1a;事件监听&#xff0c;设置显示面板&#xff0c;重新刷新验证。 ? 1 2 setContentPane(jp2);//设置显示的新面板 revalidate();/…

RocketMQ生产者和消费者都开启Message Trace后,Consume Message Trace没有消费轨迹

一、依赖 <dependency><groupId>org.apache.rocketmq</groupId><artifactId>rocketmq-spring-boot-starter</artifactId><version>2.0.3</version> </dependency>二、场景 1、生产者和消费者所属同一个程序 2、生产者开启消…

vue 老项目 npm install 报错Python,c++等相关错误

​​​ 老项目npm install 下载依赖包报错 解决方法&#xff1a; //下载python 1、 npm install --global --production windows-build-tools//配置环境 &#xff1a; 也可暂时不用配置,能用就不用配置&#xff08;npm config set python "D:\Python27\python.exe&q…

flask中的应用上下文

flask中的应用上下文 Flask应用上下文主要包含两个对象&#xff1a;current_app和g。这两个对象在处理请求期间都是全局可访问的&#xff0c;但在每个请求结束时都会被重置。 current_app&#xff1a;这是当前激活的Flask应用的实例。在大多数情况下&#xff0c;你可以将其视为…

MySQL数据库数据类型

MySQL数据库数据类型分类 在MySQL数据库中&#xff0c;MySQL数据类型分有四大类&#xff1a;数值类型、文本/二进制类型、时间日期和String类型。以下是这四大类的具体类型&#xff1a; 数值类型 数值类型的范围和字节大小&#xff1a; tinyint类型 tinyint类型只有一个字节…

【雕爷学编程】Arduino动手做(180)---Seeeduino Lotus开发板

37款传感器与执行器的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&am…

BGP汇总和破解水平分割

一&#xff0c;BGP的宣告问题 在BGP协议中每台运行BGP的设备上&#xff0c;宣告本地直连路由在BGP协议中运行BGP协议的设备来宣告&#xff0c;通过IGP学习到的&#xff0c;未运行BGP协议设备产生的路由&#xff1b; 在BGP协议中宣告本地路由表中路由条目时&#xff0c;将携带本…

葡萄叶病害数据集

1.数据集 分成训练集和测试集 训练集有四个文件夹 第一个文件夹为 Grape Black Measles&#xff08;葡萄黑麻疹&#xff09;病害&#xff08;3783张&#xff09; Grape Black rot葡萄黑腐病病害数据集&#xff08;3596张&#xff09; Grape Healthy 健康葡萄叶&#xff08;25…

【【胎教级51单片机智能小车设计】】

胎教级51单片机智能小车设计 从现在开始开一个新坑 称为创意工坊 主要更新一些有意思的设计 第一次手把手更新51单片机智能小车 胎教级教学人人都会 单片机实现的功能是通过蓝牙APP 控制小车前后左右移动 先讲明白这个小车 后续再在这个小车上更新其他的设计 成品图 第一步…

《Java-SE-第二十六章》之线程池

前言 在你立足处深挖下去,就会有泉水涌出!别管蒙昧者们叫嚷:“下边永远是地狱!” 博客主页&#xff1a;KC老衲爱尼姑的博客主页 博主的github&#xff0c;平常所写代码皆在于此 共勉&#xff1a;talk is cheap, show me the code 作者是爪哇岛的新手&#xff0c;水平很有限&…

pytorch基础实践1

数据预处理的最终目的是将我们正在处理的任何数据转换成能够感知我们神经网络的张量 基本概念 CNN的输入tensor 一般CNN的输入是一个4阶张量&#xff0c;分别用一个字母代表每个axis上的长度&#xff0c;那么它的shape为&#xff1a; [B,C,H,W] 其中 H 和 W 分别代表输入的单…

北邮22信通:第五章 邻接表图的广度遍历和深度遍历

北邮22信通一枚~ 跟随课程进度每周更新数据结构与算法的代码和文章 持续关注作者 解锁更多邮苑信通专属代码~ 获取更多文章 请访问专栏&#xff1a; 北邮22信通_青山如墨雨如画的博客-CSDN博客 目录 一.总纲 二.构造函数 2.1构造函数讲解 2.2构造函数的书写 书…

echars力引导关系图

效果图 力引导关系图 力引导布局是模拟弹簧电荷模型在每两个节点之间添加一个斥力&#xff0c;每条边的两个节点之间添加一个引力&#xff0c;每次迭代节点会在各个斥力和引力的作用下移动位置&#xff0c;多次迭代后节点会静止在一个受力平衡的位置&#xff0c;达到整个模型…

Java项目-苍穹外卖-Day01

文章目录 博客介绍软件开发流程项目介绍产品原型技术选型 博客介绍 从头开始做黑马的苍穹外卖项目 每天记录一下新学的知识点以及对应的开发进度 然后一些在项目中遇到的问题会重点标注 本篇主要是后端的&#xff0c;前端会一笔带过 软件开发流程 流程介绍需求分析需求规格说…

使用pg_prewarm缓存PostgreSQL数据库表

pg_prewarm pg_prewarm 直接利用系统缓存的代码,对操作系统发出异步prefetch请求&#xff0c;在应用中&#xff0c;尤其在OLAP的情况下&#xff0c;对于大表的分析等等是非常耗费查询的时间的&#xff0c;而即使我们使用select table的方式&#xff0c;这张表也并不可能将所有…

Eureka 学习笔记2:EurekaClient

版本 awsVersion ‘1.11.277’ EurekaClient 接口实现了 LookupService 接口&#xff0c;拥有唯一的实现类 DiscoveryClient 类。 LookupService 接口提供以下功能&#xff1a; 获取注册表根据应用名称获取应用根据实例 id 获取实例信息 public interface LookupService<…

【LeetCode】141. 环形链表 进阶题142. 环形链表 II

141. 环形链表 这道题还是用经典的快慢指针法来做。每次让快的指针走两步&#xff0c;慢的走一步。如果有环&#xff0c;则绝对会在环内的某一节点相遇。思想跟物理知识有点关系&#xff0c;如果有环&#xff0c;则在相对运动过程中&#xff0c;可以相当于慢指针静止&#xff0…