Everywhere we go, unpredictable events are waiting for us. Earthquakes, irrational actions of people, meteorites... or something simpler — a light bulb burns out, a bank card demagnetizes, a gasoline gauge breaks. We cannot disable unpredictable events, but we can at least be partially prepared for them. That is, we must prepare certain mechanisms to deal with them. In the world of programming, specifically in the Java language, events that prevent a program from functioning normally are called exceptions, and the mechanisms for preventing program crashes are called exception handling. So, when an unexpected event occurs in a program, such as division by zero, it should "throw" an exception. Exception handling is an important aspect of Java programming that helps developers manage errors and exceptions that may occur during the execution of a program. In this article, we will focus on one of the fundamental concepts of exception handling: the Java throw keyword and how to use it to throw an exception.

What is an Exception in Java?

An exception is an event that occurs during the execution of a program that disrupts the normal flow of the program's instructions. When an exception occurs, the program execution is halted, and the error message is displayed on the console. In Java, there are two types of exceptions: checked and unchecked. Checked exceptions are checked at compile time, and the compiler ensures that they are caught or declared by the calling method. On the other hand, unchecked exceptions are not checked at compile time, and they can be caught or left uncaught. Here is an example of code in which an error may occur, but the compiler skips it.

public class Factorial {
   public static long getFactorial(final int number) {
           long fact = 1;
           for (int i = 1; i <= number; i++) {
               fact = fact * i;
           }
           return fact;
   }

   public static void main(String[] args) {
       System.out.println(getFactorial(-5));
       System.out.println(getFactorial(21));

   }

}
Here is the output of the program:
1 -4249290049419214848
The program exited correctly, but produced an incorrect result. In the first case, because the function argument was negative, and the factorial doesn’t work for negative numbers. In the second case, the result was wrong, because the number is too large to count its factorial in the range of long type. Here is another example. Let's write a program in which we will divide one number by another.

public class DivisionExample {

       public static void main(String[] args) {
           int a = 10;
           int b = 0;
           int result = divide(a, b);
           System.out.println(result);
       }

       public static int divide(int a, int b) {
           return a / b;
       }
}
In this example, an ArithmeticException is going to be thrown because the variable b is zero. However, this error is not handled, so the program exits with an incorrect status.

How to throw an exception in Java

In Java, exceptions are also objects, so an exception is thrown just like a new Exception object created. An exception is thrown in a program using the throw statement. Usually, these two operations (object creation and throwing an exception) are combined into one:

 throw new Exception("error…");
The throw keyword in Java is used to throw an exception from a method or block of code when an error or exceptional condition occurs that the program cannot handle at runtime. The program flow is redirected to the closest catch block. This block can manage the exception.

Example of the 'throw' keyword usage

To illustrate the functionality of the throw keyword in Java, let's take an example. Let’s write a method to compute the factorial of a number. If the number is negative, it can’t be computed, so an exception must be thrown. Similarly, if the number is too large, the factorial result will exceed the maximum size of a long type, and another exception is going to be thrown. Here we have an implementation of the method:

public Class Factorial {

public static long getFactorial(final int number) {
   if ((number >= 0) && (number < 21)) {
       long fact = 1;
       for (int i = 1; i <= number; i++) {
           fact = fact * i;
       }
       return fact;
   } else {

//throw new exception here 
       throw new IllegalArgumentException("THe argument isn't legal");
   }
}

 public static void main(String[] args) {
       System.out.println(getFactorial(-5));
       System.out.println(getFactorial(21));

   }
}
In this example, if the value of number is negative, the throw keyword is used to throw an instance of the IllegalArgumentException class. If you run the program, "The argument isn’t legal" message will be displayed on the console. The program execution will be halted.

No more errors: catching an exception example

Now let's recall the second example, with division by zero, and execute it with exception handling.

public class DivisionExample {

    public static void main(String[] args) {
        int a = 10;
        int b = 0;
        try {
            int result = divide(a, b);
            System.out.println(result);
        } catch (ArithmeticException e) {
            System.out.println("Error: division by zero");
        }
    }

    public static int divide(int a, int b) {
        return a / b;
    }
}
In this example, we've added a try-catch construct to handle the division-by-zero exception. Briefly speaking, try-catch-finally is a Java programming language construct that allows you to handle exceptions and execute code regardless of whether an exception occurred or not. try-catch-finally consists of three blocks:
  • The try block. Potentially dangerous code is being executed here. That is code that can throw an exception. If an exception occurs within a try block, execution of the code in that block is aborted, and control is transferred to the catch block.
  • The catch block. Here the thrown exception is handled. In the catch block, you can specify which exception to catch and what logic to execute when it is caught.
  • The finally block. This one is executed regardless of whether an exception occurred or not. The finally block is used, for example, to release resources (such as closing a file or socket) that were allocated in a try block. You can omit this block.
The try-catch-finally construct allows for more precise control over program execution in the event of exceptional situations and helps prevent unexpected termination of the program in the event of errors. Now, let’s go back to our example. If division by zero occurs during the divide method, an ArithmeticException will be thrown, which is caught by the catch block. In the catch block, we simply print an error message to the console. If no exception occurs, the program will continue its execution.

throws keyword

The throws keyword is used in the method signature. If so, it means that an exception is being thrown in the method. This can propagate exceptions up the call stack and indicate that exceptions do not need to be handled in the current method. In Java, "throws" can also be used to refer to custom exceptions defined in a program. Java throw Exception - 1For example, a method may perform a division of two numbers but throw an IllegalArgumentException if the second argument is zero:

public static double divide(double a, double b) throws IllegalArgumentException {
    if (b == 0) {
        throw new IllegalArgumentException("Division by zero is not allowed");
    }
    return a / b;
}
This method uses the throws keyword to indicate that an IllegalArgumentException can be thrown if the second argument is null. If such an exception occurs while executing the method, it will be passed to the calling method for processing. Method call example:

public static void main(String[] args) {
    double result = 0;
    try {
        result = divide(10, 0);
    } catch (IllegalArgumentException e) {
        System.out.println("Error: " + e.getMessage());
    }
    System.out.println("Result: " + result);
}
In this example, the divide() method is called with arguments 10 and 0, which will throw an IllegalArgumentException due to division by zero being impossible. The exception will be caught by a try-catch block, and an error message will be displayed. The program will result in a value of zero since the exception terminates the execution of the divide() method.