怎样进入国外网站,湖北正规网站建设质量保障,政协网站建设方案,义乌外贸建网站文章目录 什么是异常抛出异常通过异常信息解决异常捕获异常 什么是异常
我们在运行程序时#xff0c;如果代码出现了语法问题或逻辑问题#xff0c;会导致程序编译失败或退出#xff0c;称为异常。运行结果会给出一个一长串的红色字#xff0c;通常会给出异常信息#xf… 文章目录 什么是异常抛出异常通过异常信息解决异常捕获异常 什么是异常
我们在运行程序时如果代码出现了语法问题或逻辑问题会导致程序编译失败或退出称为异常。运行结果会给出一个一长串的红色字通常会给出异常信息异常名、调用堆栈等。
语法错误会直接导致编译失败不能被代码捕获而逻辑异常一般是在运行时抛出的可以捕获。
语法错误
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 kotlinSinceKotlin(1.1) public actual typealias Error java.lang.Error
SinceKotlin(1.1) public actual typealias Exception java.lang.Exception
...NoteKotlin 是支持跨平台的并且有相应的分支Kotlin/Jvm桌面端、安卓Android、Kotlin/Native原生平台如苹果 iOS、Kotlin/JS网页端 JavaScript、Kotlin/Wasm网页端 Assembly。 Kotlin 跨平台项目有expect和actual关键字分别用于声明全平台期望内容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值如果message是null则不会有冒号及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大致是分为两大类的Exception、Error。我的声明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还能用于赋值这与if 或when类似
fun main() {val msg try {throw Throwable(抛出异常)顺利执行}catch (e: Throwable) {出现异常}print(msg)
}出现异常