If the execution of a function can't be completed, an exception can be thrown. The most common causes of this are listed as follows:
- Invalid incoming data
- A file cannot be found
- Termination of a network connection
- Java Virtual Machine needs more available memory
The throw keyword is used to interrupt the execution of a current function and to notify a caller about an exceptional event. Let's look at the constructor of the FileInputStream class:
public FileInputStream(File file) throws FileNotFoundException {
String name = (file != null ? file.getPath() : null);
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkRead(name);
}
if (name == null) {
throw new NullPointerException();
}
if (file.isInvalid()) {
throw new FileNotFoundException("Invalid file path");
}
fd = new FileDescriptor();
fd.attach(this);
path = name;
open(name);
}
As you can see, if a path to a file is invalid and the file can't be found, FileNotFoundException is thrown. The signature of a constructor is marked with the throw keyword as well as exceptions that can be thrown by this function. In Kotlin, the @Throws annotation is used instead of the throw keyword:
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER, AnnotationTarget.CONSTRUCTOR)
@Retention(AnnotationRetention.SOURCE)
public annotation class Throws(vararg val exceptionClasses: KClass<out Throwable>)
In most cases, we should wrap an invoking of a function that can throw an exception in the try { ... } catch { ... } block. In other cases, an exception can be thrown, as demonstrated in the following example:
@Throws(IOException::class)
fun main(args: Array<String>) {
FileInputStream("invalid/path")
}
The output of this example is as follows:
Exception in thread "main" java.io.FileNotFoundException: invalid/path (No such file or directory)
at java.io.FileInputStream.open0(Native Method)
at java.io.FileInputStream.open(FileInputStream.java:195)
at java.io.FileInputStream.<init>(FileInputStream.java:138)
at java.io.FileInputStream.<init>(FileInputStream.java:93)
at chapter10.Example1Kt.main(Example1.kt:6)
However, if we want to handle this exception, we should use the try { ... } catch { ... } block:
fun main(args: Array<String>) {
try {
FileInputStream("invalid/path")
} catch (exception: Exception) {
println("${exception::class.java.name} was handled!")
}
}
The output looks like this:
java.io.FileNotFoundException was handled!
If a function throws different types of exceptions, you can define several catch blocks:
try {
FileInputStream("invalid/path")
} catch (exception: FileAlreadyExistsException) {
println("${exception::class.java.name} was handled!")
} catch (exception: IOException) {
println("${exception::class.java.name} was handled!")
} catch (exception: Exception) {
println("${exception::class.java.name} was handled!")
}
If the try { ... } catch { ... } block catches an exception, the execution of a function won't be interrupted. The following example demonstrates this:
fun main(args: Array<String>) {
try {
FileInputStream("invalid/path")
} catch (exception: FileAlreadyExistsException) {
println("${exception::class.java.name} was handled!")
} catch (exception: IOException) {
println("${exception::class.java.name} was handled!")
} catch (exception: Exception) {
println("${exception::class.java.name} was handled!")
}
println("Done!")
}
The following is the output:
java.io.FileNotFoundException was handled!
Done!
An instance of the Exception type contains different information about an error that has occurred. For instance, you can get the following message:
fun main(args: Array<String>) {
try {
FileInputStream("invalid/path")
} catch (exception: IOException) {
println(exception.message)
}
}
The output is as follows:
invalid/path (No such file or directory)
Alternatively, you can invoke the printStackTrace() method:
fun main(args: Array<String>) {
try {
FileInputStream("invalid/path")
} catch (exception: IOException) {
exception.printStackTrace()
}
}
The following is the output:
java.io.FileNotFoundException: invalid/path (No such file or directory)
at java.io.FileInputStream.open0(Native Method)
at java.io.FileInputStream.open(FileInputStream.java:195)
at java.io.FileInputStream.<init>(FileInputStream.java:138)
at java.io.FileInputStream.<init>(FileInputStream.java:93)
at Chapter10.Example1Kt.main(Example1.kt:9)