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

Kotlin 异常处理

文章目录

  • 什么是异常
  • 抛出异常
  • 通过异常信息解决异常
  • 捕获异常

什么是异常

我们在运行程序时,如果代码出现了语法问题或逻辑问题,会导致程序编译失败或退出,称为异常。运行结果会给出一个一长串的红色字,通常会给出异常信息(异常名、调用堆栈等)。

语法错误会直接导致编译失败,不能被代码捕获;而逻辑异常一般是在运行时抛出的,可以捕获。

语法错误:

fun main() {print("Hello Kotlin"
}
// 异常信息(部分)
e: file:///D:/Project/Kotlin/Normal/untitled/src/main/kotlin/Main.kt:2:25 Expecting ')'FAILURE: Build failed with an exception.* What went wrong:
Execution failed for task ':compileKotlin'.
> A failure occurred while executing org.jetbrains.kotlin.compilerRunner.GradleCompilerRunnerWithWorkers$GradleKotlinCompilerWorkAction> Compilation error. See log for more details

逻辑错误:

fun main() {val list = listOf(1, 2, 3)print(list[3])
}
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3at java.base/java.util.Arrays$ArrayList.get(Arrays.java:4266)at MainKt.main(Main.kt:4)at MainKt.main(Main.kt)

每一个异常都是一个Throwable的对象,这是一个 Java 的类。

public class Throwable implements Serializable {...
}

其实,Kotlin 中的异常来自于 Java 异常,并且使用typealias起了别名。

// Typealias.kt
package kotlin@SinceKotlin("1.1") public actual typealias Error = java.lang.Error
@SinceKotlin("1.1") public actual typealias Exception = java.lang.Exception
...

Note:Kotlin 是支持跨平台的,并且有相应的分支,Kotlin/Jvm(桌面端、安卓Android)、Kotlin/Native(原生平台,如苹果 iOS)、Kotlin/JS(网页端 JavaScript)、Kotlin/Wasm(网页端 Assembly)。
Kotlin 跨平台项目有expectactual关键字,分别用于声明全平台期望内容(expect)以及各个平台的实现内容(actual)。以上的代码前方都标记了actual,说明这是平台代码,各个平台之间代码会有所差异,Jvm 平台有 Java,而其他平台没有。

从源码中可以发现,并没有Throwable的别名,Kotlin 创建了一个自己的Throwable对象。应该是为了跨平台兼容,其他平台没有 Java 也就没有java.lang.Throwable(其他平台应该是继承自kotlin.Throwable),在实际使用中我们用的是kotlin.Throwable

// Throwable.kt
package kotlinpublic open class Throwable(open val message: String?, open val cause: Throwable?) {constructor(message: String?) : this(message, null)constructor(cause: Throwable?) : this(cause?.toString(), cause)constructor() : this(null, null)
}

抛出异常

我们可以使用throw抛出一个Throwable(不能是java.lang.Throwable),我们可以实例化Throwable或其子类,使用throw将其抛出,后续代码将不再执行。

fun main() {throw Throwable("你好,异常")print("Hello Kotlin")
}
Exception in thread "main" java.lang.Throwable: 你好,异常at MainKt.main(Main.kt:2)at MainKt.main(Main.kt)

通过异常信息解决异常

异常信息(红色字)是我们解决异常的关键。我们可以从异常信息中找到异常的名称以及抛出位置。

通常情况下,异常信息会非常长,异常信息的格式其实是固定的,异常名称、信息message值和抛出位置会在开头处,我们可以看一下下方的异常信息。

首先在开头处我们便可以得知在main这一线程(thread)中出现了一个异常(Exception in thread "main"),并且在后边跟着它的名称java.lang.Throwable,冒号:后面是异常的message值,如果messagenull,则不会有冒号及message的内容。

一般情况下,你只需要搜索第一行的信息,便会找到解决办法。当然,为了与Java 区分开,你可以在信息前加 Kotlin。

后边的就是调用堆栈,在这里可以找到异常抛出处,我们要注意那些蓝色字体(在 IDEA 中,Main.kt:2是蓝色的。Main.kt表示文件名;2表示行数,有时候会对不上),点击它光标会定位到该位置。越靠前的,就越靠近异常抛出位置。

有些时候,在中间位置也会出现类似Cause by ...的内容,也需要特别留意,可以像搜索第一行一样搜索它。

fun main() {throw Throwable("抛出异常")
}
Exception in thread "main" java.lang.Throwable: 抛出异常at MainKt.main(Main.kt:2)at MainKt.main(Main.kt)

捕获异常

有些情况下,我们并不希望异常直接抛出,例如,在安卓 Android 应用中,抛出异常将直接导致应用闪退,这是非常不好的体验。我们可以使用try-catch-finall来捕获异常。

finall可以缺省,我们先从简单的try-catch讲起。我们在try的花括号{}里可以写一段要执行的可能发生异常的代码,在后边补上catch,小括号()中需要写一个变量名称: Throwable 或其子类,表示你要捕获的异常,接着在catch花括号{}里写上捕获异常后要做什么,这里我们打印异常的消息,这是一个String?类型。

fun main() {try {// 这是一段要执行的代码println("try 1")throw Exception("异常消息")print("try 2")}catch (e: Exception) {// 如果上方代码抛出了异常// 则该地方可以尝试捕获异常print(e.message)}
}
try 1
异常消息

可以看到结果中没有异常了。如果我们去掉异常抛出语句,try中的内容会顺利执行,并且不会执行catch的内容:

fun main() {try {// 这是一段要执行的代码println("try 1")// throw Exception("异常消息")print("try 2")}catch (e: Exception) {// 如果上方代码抛出了异常// 则该地方可以尝试捕获异常print(e.message)}
}
try 1
try 2

这里需要注意,如果抛出的异常与catch圆括号中的类型不是同一类(不一定要类型相同,抛出异常也可以是圆括号中类型的子类),会捕获失败,抛出异常。这里举一个我一直以来都犯的错误,我会习惯性地把e的类型给成Exception,可是Throwable大致是分为两大类的:ExceptionError。我的声明e: Exception只对Exception及其子类生效,如果某一次它抛出了Error,将会捕获失败。

import java.awt.AWTErrorfun main() {try {// AWTError: Errorthrow AWTError("AWT 错误")}catch (e: Exception) {print(e.message)}
}
Exception in thread "main" java.awt.AWTError: AWT 错误at MainKt.main(Main.kt:6)at MainKt.main(Main.kt)

所以建议大家,还是把它的类型写为Throwable

fun main() {try {// AWTError: Errorthrow AWTError("AWT 错误")}catch (e: Throwable) {print(e.message)}
}
AWT 错误

最后是finally,它不管是否抛出异常,都会执行相应的代码:

// 将 block 函数交给 catching 函数调用
inline fun catching(block: () -> Unit) {try {// 调用 block 函数block()} catch (_: Throwable) {// 空语句需要将 e 命名为 _} finally {println("Finally")}
}fun main() {// 抛出异常catching { throw Throwable() }// 不抛出异常catching {  }
}
Finally
Finally

try-catch-finally还能用于赋值,这与ifwhen类似:

fun main() {val msg = try {throw Throwable("抛出异常")"顺利执行"}catch (e: Throwable) {"出现异常"}print(msg)
}
出现异常

相关文章:

Kotlin 异常处理

文章目录 什么是异常抛出异常通过异常信息解决异常捕获异常 什么是异常 我们在运行程序时,如果代码出现了语法问题或逻辑问题,会导致程序编译失败或退出,称为异常。运行结果会给出一个一长串的红色字,通常会给出异常信息&#xf…...

nltk下载报错

捣鼓voice_clone时报错: 报错信息: mport nltk nltk.download(‘cmudict’)For more information see: https://www.nltk.org/data.htmlAttempted to load tokenizers/punkt/PY3/english.pickleSearched in: - ‘/home/zhangshuai/nltk_data’ - ‘/hom…...

Vulnhub-DC5

靶机IP:192.168.20.139 kaliIP:192.168.20.128 网络有问题的可以看下搭建Vulnhub靶机网络问题(获取不到IP) 信息收集 nmap扫下端口及版本 dirsearch扫下目录 LinuxphpNginx 环境 我们再去看前端界面,发现在contact界面有能提交的地方,但是经过测试不…...

pytorch 笔记:pytorch 优化内容(更新中)

1 Tensor创建类 1.1 直接创建Tensor,而不是从Python或Numpy中转换 不要使用原生Python或NumPy创建数据,然后将其转换为torch.Tensor直接用torch.Tensor创建或者直接:torch.empty(), torch.zeros(), torch.full(), torch.ones(), torch.…...

vue 创建一个新项目 以及 手动配置选项

【Vue】3.0 项目创建 自定义配置_vue3.0-CSDN博客...

c#快速获取超大文件夹文件名

c#快速获取超大文件夹文件名 枚举集合速度快&#xff1a;(10万个文件) //by txwtech IEnumerable<string> files2 Directory.EnumerateFiles("d:\aa", "*.xml", SearchOption.TopDirectoryOnly);//过滤指定查询xml文件 慢&#xff1a; var fi…...

华为OD技术面试-最小异或-2024手撕代码真题

题目:最小异或 给你两个正整数 num1 和 num2 ,找出满足下述条件的正整数 x : x 的置位数和 num2 相同,且 x XOR num1 的值 最小 注意 XOR 是按位异或运算。 返回整数 x 。题目保证,对于生成的测试用例, x 是 唯一确定 的。 整数的 置位数 是其二进制表示中 1 的数目。 示…...

基于SpringBoot+Vue单位考勤系统设计和实现(源码+LW+调试文档+讲解等)

&#x1f497;博主介绍&#xff1a;✌全网粉丝1W,CSDN作者、博客专家、全栈领域优质创作者&#xff0c;博客之星、平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌&#x1f497; &#x1f31f;文末获取源码数据库&#x1f31f; 感兴趣的可以先收藏起来&#xff0c;还…...

Anaconda软件:安装、管理python相关包

Anaconda的作用 一个python环境中需要有一个解释器, 和一个包集合. 解释器&#xff1a; 根据python的版本大概分为2和3. python2和3之间无法互相兼容, 也就是说用python2语法写出来的脚本不一定能在python3的解释器中运行. 包集合&#xff1a;包含了自带的包和第三方包, 第三…...

pinia 重置状态插件

一、前言 测试提出&#xff0c;登出登录后&#xff0c;再次进入页面后。页面的查询项非初始状态。检查后发现&#xff0c;是因为查询项的值存到了store呢&#xff0c;从store中获取&#xff0c;故需要一个重置store的方法 二、pinia 查阅pinia官网后&#xff0c;发现pinia提…...

一千题,No.0049(跟奥巴马一起编程)

美国总统奥巴马不仅呼吁所有人都学习编程&#xff0c;甚至以身作则编写代码&#xff0c;成为美国历史上首位编写计算机代码的总统。2014 年底&#xff0c;为庆祝“计算机科学教育周”正式启动&#xff0c;奥巴马编写了很简单的计算机代码&#xff1a;在屏幕上画一个正方形。现在…...

《python程序语言设计》2018版第5章第46题均值和标准方差-上部(我又一次被作者的出题击倒)

第N次被作者打倒了&#xff0c;第5章46题解题上集的记录 计算均值的代码段 step_num 0num_c 0 pow_c 0 while step_num < 10:a eval(input("Enter number is: "))num_c apow_c pow(a, 2)step_num 1 t2 num_c / 10这个结果和书里的答案差一点。书里写的是…...

自己做的精灵图制作,图片合成,卓宠,窗口置顶,磁力链下载等工具软件

欢迎使用和提bug&#xff0c;才v1.0.2&#xff0c;有新奇的自己需要的功能可以提给我&#xff0c;我看看能不能做。 网站地址 github...

C++协程

什么是协程 协程&#xff08;Coroutine&#xff09;是程序组件&#xff0c;可以在执行过程中暂停并在稍后继续执行。与传统的子例程&#xff08;如函数或过程&#xff09;不同&#xff0c;子例程一旦调用&#xff0c;必须等其返回后才能继续执行调用它的代码。协程则可以在执行…...

linux系统——ping命令

ping命令可以用来判断对远端ip的连通性&#xff0c;可以加域名也可以加公共ip地址 这里发送出56字节&#xff0c;返回64字节...

vue3第三十七节(自定义插件之自定义指令)防重指令

引言&#xff1a;自定义指令&#xff0c;我们可以通过插件的形式进行全局注册&#xff1a; 例如&#xff1a;在提交按钮请求接口时候&#xff0c;为了防止重复提交&#xff0c;而导致的请求资源浪费&#xff0c;或者是新增提交时候&#xff0c;防止新增相同的数据。 我们的全局…...

面试高频问题----5

一、线程池参数的执行顺序 1.如果线程池中的线程数量小于核心线程数&#xff0c;则创建新的线程来处理任务 2.如果线程池中的线程数量等于核心线程数&#xff0c;但工作队列未满&#xff0c;将任务放入工作队列中执行 3.如果工作队列已满&#xff0c;但线程数小于最大线程数…...

计算机网络 —— 网络层(子网掩码和子网划分)

计算机网络 —— 网络层&#xff08;子网掩码和子网划分&#xff09; 网络地址转换NAT子网掩码和子网划分举个例子第一步&#xff1a;看类型第二步&#xff1a;从主机号开始比对第三步&#xff1a;去头去尾 我们今天来看子网掩码和子网划分&#xff1a; 网络地址转换NAT 网络…...

2024 IDEA最新永久使用码教程(2099版)

本篇文章我就来分享一下2024年当前最新版 IntelliJ IDEA 最新注册码&#xff0c;教程如下&#xff0c;可免费永久&#xff0c;亲测有效&#xff0c;适合Windows和Mac。 本教程适用于 J B 全系列产品&#xff0c;包括 Pycharm、IDEA、WebStorm、Phpstorm、Datagrip、RubyMine、…...

http协议,tomcat的作用

HTTP 概念:Hyper Text Transfer Protocol&#xff0c;超文本传输协议&#xff0c;规定了浏览器和服务器之间数据传输的规则。 特点: 1.基于TCP协议:面向连接&#xff0c;安全 2. 基于请求-响应模型的:一次请求对应一次响应 3HTTP协议是无状态的协议:对于事务处理没有记忆能…...

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇&#xff0c;在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下&#xff1a; 【Note】&#xff1a;如果你已经完成安装等操作&#xff0c;可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作&#xff0c;重…...

【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验

系列回顾&#xff1a; 在上一篇中&#xff0c;我们成功地为应用集成了数据库&#xff0c;并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了&#xff01;但是&#xff0c;如果你仔细审视那些 API&#xff0c;会发现它们还很“粗糙”&#xff1a;有…...

CMake 从 GitHub 下载第三方库并使用

有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...

聊一聊接口测试的意义有哪些?

目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开&#xff0c;首…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码

目录 一、&#x1f468;‍&#x1f393;网站题目 二、✍️网站描述 三、&#x1f4da;网站介绍 四、&#x1f310;网站效果 五、&#x1fa93; 代码实现 &#x1f9f1;HTML 六、&#x1f947; 如何让学习不再盲目 七、&#x1f381;更多干货 一、&#x1f468;‍&#x1f…...

代码随想录刷题day30

1、零钱兑换II 给你一个整数数组 coins 表示不同面额的硬币&#xff0c;另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额&#xff0c;返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带…...

人工智能--安全大模型训练计划:基于Fine-tuning + LLM Agent

安全大模型训练计划&#xff1a;基于Fine-tuning LLM Agent 1. 构建高质量安全数据集 目标&#xff1a;为安全大模型创建高质量、去偏、符合伦理的训练数据集&#xff0c;涵盖安全相关任务&#xff08;如有害内容检测、隐私保护、道德推理等&#xff09;。 1.1 数据收集 描…...

C# winform教程(二)----checkbox

一、作用 提供一个用户选择或者不选的状态&#xff0c;这是一个可以多选的控件。 二、属性 其实功能大差不差&#xff0c;除了特殊的几个外&#xff0c;与button基本相同&#xff0c;所有说几个独有的 checkbox属性 名称内容含义appearance控件外观可以变成按钮形状checkali…...

PH热榜 | 2025-06-08

1. Thiings 标语&#xff1a;一套超过1900个免费AI生成的3D图标集合 介绍&#xff1a;Thiings是一个不断扩展的免费AI生成3D图标库&#xff0c;目前已有超过1900个图标。你可以按照主题浏览&#xff0c;生成自己的图标&#xff0c;或者下载整个图标集。所有图标都可以在个人或…...

2025-05-08-deepseek本地化部署

title: 2025-05-08-deepseek 本地化部署 tags: 深度学习 程序开发 2025-05-08-deepseek 本地化部署 参考博客 本地部署 DeepSeek&#xff1a;小白也能轻松搞定&#xff01; 如何给本地部署的 DeepSeek 投喂数据&#xff0c;让他更懂你 [实验目的]&#xff1a;理解系统架构与原…...