Introduction
The throw keyword in Kotlin is used to explicitly throw an exception. Throwing an exception disrupts the normal flow of the program, and it can be caught and handled using try-catch blocks. This chapter will cover how to use the throw keyword to throw exceptions, create custom exceptions, and handle them properly.
Throwing Exceptions
You can throw an exception using the throw keyword followed by an instance of the exception class.
Syntax
throw ExceptionType("Exception message")
Example
fun main() {
try {
validateAge(15)
} catch (e: IllegalArgumentException) {
println("Exception caught: ${e.message}")
}
}
fun validateAge(age: Int) {
if (age < 18) {
throw IllegalArgumentException("Age must be at least 18")
}
}
Explanation:
throw IllegalArgumentException("Age must be at least 18"): Throws anIllegalArgumentExceptionif the age is less than 18.
Output:
Exception caught: Age must be at least 18
Creating Custom Exceptions
You can create custom exceptions by extending the Exception class or any of its subclasses.
Example
fun main() {
try {
validateName("")
} catch (e: InvalidNameException) {
println("Exception caught: ${e.message}")
}
}
class InvalidNameException(message: String) : Exception(message)
fun validateName(name: String) {
if (name.isEmpty()) {
throw InvalidNameException("Name cannot be empty")
}
}
Explanation:
class InvalidNameException(message: String) : Exception(message): Defines a custom exception classInvalidNameException.throw InvalidNameException("Name cannot be empty"): Throws the custom exception if the name is empty.
Output:
Exception caught: Name cannot be empty
Using throw in Functions
You can use throw within functions to signal error conditions.
Example
fun main() {
try {
val result = divide(10, 0)
println("Result: $result")
} catch (e: ArithmeticException) {
println("Exception caught: ${e.message}")
}
}
fun divide(a: Int, b: Int): Int {
if (b == 0) {
throw ArithmeticException("Division by zero")
}
return a / b
}
Explanation:
throw ArithmeticException("Division by zero"): Throws anArithmeticExceptionif the divisor is zero.
Output:
Exception caught: Division by zero
Re-throwing Exceptions
You can catch an exception, perform some operations, and then re-throw the exception if needed.
Example
fun main() {
try {
processFile("non_existent_file.txt")
} catch (e: Exception) {
println("Exception caught in main: ${e.message}")
}
}
fun processFile(filename: String) {
try {
val file = java.io.FileReader(filename)
// Process the file
} catch (e: java.io.FileNotFoundException) {
println("File not found: ${e.message}")
throw e // Re-throwing the exception
}
}
Explanation:
throw e: Re-throws the caughtFileNotFoundExceptionafter logging the error message.
Output:
File not found: non_existent_file.txt (No such file or directory)
Exception caught in main: non_existent_file.txt (No such file or directory)
Using throw with Nothing Type
In Kotlin, throw is an expression and its type is Nothing. This type indicates that the expression does not return any value.
Example
fun main() {
try {
checkValue(-1)
} catch (e: IllegalArgumentException) {
println("Exception caught: ${e.message}")
}
}
fun checkValue(value: Int) {
if (value < 0) {
throw IllegalArgumentException("Value must be non-negative")
}
println("Value is $value")
}
Explanation:
throw IllegalArgumentException("Value must be non-negative"): Thethrowexpression does not return any value, and its type isNothing.
Output:
Exception caught: Value must be non-negative
Example Program with throw
Here is an example program that demonstrates various aspects of using the throw keyword in Kotlin:
fun main() {
// Using throw to signal error conditions
try {
validateAge(15)
} catch (e: IllegalArgumentException) {
println("Exception caught: ${e.message}")
}
// Using custom exceptions
try {
validateName("")
} catch (e: InvalidNameException) {
println("Exception caught: ${e.message}")
}
// Using throw in functions
try {
val result = divide(10, 0)
println("Result: $result")
} catch (e: ArithmeticException) {
println("Exception caught: ${e.message}")
}
// Re-throwing exceptions
try {
processFile("non_existent_file.txt")
} catch (e: Exception) {
println("Exception caught in main: ${e.message}")
}
// Using throw with Nothing type
try {
checkValue(-1)
} catch (e: IllegalArgumentException) {
println("Exception caught: ${e.message}")
}
}
fun validateAge(age: Int) {
if (age < 18) {
throw IllegalArgumentException("Age must be at least 18")
}
}
class InvalidNameException(message: String) : Exception(message)
fun validateName(name: String) {
if (name.isEmpty()) {
throw InvalidNameException("Name cannot be empty")
}
}
fun divide(a: Int, b: Int): Int {
if (b == 0) {
throw ArithmeticException("Division by zero")
}
return a / b
}
fun processFile(filename: String) {
try {
val file = java.io.FileReader(filename)
// Process the file
} catch (e: java.io.FileNotFoundException) {
println("File not found: ${e.message}")
throw e // Re-throwing the exception
}
}
fun checkValue(value: Int) {
if (value < 0) {
throw IllegalArgumentException("Value must be non-negative")
}
println("Value is $value")
}
Output:
Exception caught: Age must be at least 18
Exception caught: Name cannot be empty
Exception caught: Division by zero
File not found: non_existent_file.txt (No such file or directory)
Exception caught in main: non_existent_file.txt (No such file or directory)
Exception caught: Value must be non-negative
Conclusion
In this chapter, you learned about the throw keyword in Kotlin, including how to use it to throw exceptions, create custom exceptions, handle exceptions, and use throw with the Nothing type. Understanding how to throw and handle exceptions is crucial for writing robust and maintainable Kotlin programs.