➤ How to Code a Game
➤ Array Programs in Java
➤ Java Inline Thread Creation
➤ Java Custom Exception
➤ Hibernate vs JDBC
➤ Object Relational Mapping
➤ Check Oracle DB Size
➤ Check Oracle DB Version
➤ Generation of Computers
➤ XML Pros & Cons
➤ Git Analytics & Its Uses
➤ Top Skills for Cloud Professional
➤ How to Hire Best Candidates
➤ Scrum Master Roles & Work
➤ CyberSecurity in Python
➤ Protect from Cyber-Attack
➤ Solve App Development Challenges
➤ Top Chrome Extensions for Twitch Users
➤ Mistakes That Can Ruin Your Test Metric Program
Exception Handling Interview Questions in Java & Spring | Also see:- Exception Handling in Java, Develop User-defined Custom exception, Java Custom Exception Example, Exception Handling in Spring Boot REST
1. What is an exception?
The exception is an abnormal condition that occurs during the execution of a program and disrupts the normal flow of the program. If not handled properly it can cause the program to terminate abruptly.
2. How do we handle exceptions in Java?
Using try, catch block.
- Try:- Encloses a set of statements that can throw exceptions and hence are required to be monitored.
- Catch:- When an exception occurs, this block catches that exception and works accordingly to handle it or to throw it as required.
- Finally:- This block always gets executed regardless of exception occurrence. Hence clean up is done here.
3. Hierarchy of Exception?

The java.lang.Throwable:- It is the root class of the exception hierarchy. It has two main branches:
- Error:- These are serious problems that applications should not try to catch. Subclasses:-
- StackOverflowError
- OutOfMemoryError
- VirtualMachineError
- Exception
- Checked exceptions: Must be declared or handled.
- IOException
- E.g., FileNotFoundException, EOFException
- SQLException
- ClassNotFoundException
- InvocationTargetException
- InterruptedException
- NoSuchMethodException
- CloneNotSupportedException
- IOException
- RuntimeException: These are unchecked exceptions and do not need to be declared or handled. Subclasses:-
- NullPointerException
- ArrayIndexOutOfBoundsException
- StringIndexOutOfBoundsException
- NegativeArraySizeException
- ArithmeticException
- ClassCastException
- IllegalArgumentException
- E.g., NumberFormatException
- IllegalStateException
- Checked exceptions: Must be declared or handled.
4. Difference between Exception and Error?
Both Errors and Exceptions in Java represent abnormal conditions, but errors are usually indicative of serious problems at the system level, while exceptions are typically recoverable and can be handled by application code. Errors are instances of the `Error` class or its subclasses, while exceptions are instances of the `Exception` class or its subclasses, including `RuntimeException` and its subclasses.
Exception | Error |
We can recover from exceptions using a try-catch block or using throw. | Recovering from Error is not possible. |
The compiler will have knowledge about checked Exceptions hence Compiler will force you to use try-catch blocks. | The compiler will not have any knowledge about unchecked exceptions and Errors |
Exceptions are related to the application | Errors are related to the environment where the application is running |
Exceptions include both checked as well as unchecked types. | All errors in Java are unchecked type. |
Exceptions in Java are of type java.lang.Exception. | Errors in java are of type java.lang.Error. |
5. Can we write only try block without a catch and finally blocks?
No. either catch or finally is a must.
6. If no then what error will come?
Compile time error saying “insert finally to complete try statement”.
7. Can we write any other statements between try catch or finally block?
No. Try must be followed directly by either catch or finally.
8. Do remaining statements in the try block execute after an exception occurs?
No. If an exception occurs at a particular point in the try block then all statements after that statement where the exception occurred will not be executed and the flow goes directly to the catch block (if there is any) else the program terminates. Hence we need the finally block to do all the cleaning up like closing files or removing locks.
9. throw vs throws in Java?
In Java, throw and throws are both related to exception handling, but they serve different purposes:
1. throw:-
- The throw keyword is used to explicitly throw an exception within a method or a block of code.
- When we use throw, we are raising an exception manually, typically when some error condition occurs that cannot be handled within the normal flow of execution.
- We can throw any subclass of Throwable, including Exception or Error, and even custom exception classes that you define.
Example:
public void someMethod() {
if (errorCondition) {
throw new SomeException("Error message");
}
}
2. throws:-
- The `throws` keyword is used in method declarations to indicate that the method may throw certain types of exceptions during its execution.
- When we use `throws` in a method signature, we are essentially declaring that the method might not handle the exception itself but will pass it on to the caller.
- It specifies the exceptions that can be thrown by the method but doesn’t throw any exceptions itself.
Example:-
public void someMethod() throws SomeException {
// Method code that may throw SomeException
}
Multiple exceptions can be declared using a comma-separated list:-
public void someMethod() throws ExceptionType1, ExceptionType2 {
// Method code that may throw ExceptionType1 or ExceptionType2
}
In summary:-
- throw is used to raise an exception explicitly within a method or block of code.
- throws is used in method declarations to indicate which exceptions the method may throw, leaving it to the caller to handle or propagate them further.
throw | throws |
The Java “throw” keyword is used to explicitly throw an exception. | Java “throws” keyword is used to declare an exception. |
Checked exceptions cannot be propagated using throw only. | Checked exceptions can be propagated with throws. |
Throw is used within the method. | Throws is used with the method signature. |
You cannot throw multiple exceptions. | You can declare multiple exceptions. |
10. What happens when an exception is thrown by the main method?
When an exception is thrown by the main() method, Java Runtime terminates the program and prints the exception message and the stack trace in the system console. Since main() is the entry point and doesn’t have a caller method therefore exception propagation doesn’t happen.
11. What do you understand by an unreachable catch block error?
This error comes when you keep superclasses first and subclasses later. Like below, we kept Exception which is the parent of NullPointerException.
try {
System.out.println("Test.main()");
} catch(Exception e) {
System.out.println(e.getMessage());
} catch(NullPointerException npe) { // error: unreachable catch block
System.out.println(npe.getMessage());
}
Hence the order of catch blocks must be from the most specific to the most general ones.
12. What is the multi-catch block?
To reduce code duplication and make it easier to maintain, Java 7 came up with this multi-catch block concept.
Here are the catch block arguments that have different expectations piped. Example:-
try {
// ....
} catch(NullPointerException | SQLException ex) {
// ....
}
13. What is the difference between final, finally, and finalize in Java?
- final:- It is a keyword used to apply restriction on the class, method, and variable. The final class can’t be inherited. The final method can not be overridden and the final variable can not be changed after initialization.
- finally:- This keyword is used with the try-catch block to provide statements that will always get executed even if some exception arises. Usually, finally is used to close resources.
- finalize:- It performs clean-up processing just before the object is garbage collected.
14. Checked Vs Unchecked Exception

Checked | Unchecked Exceptions | |
Another Name | Checked exceptions are checked by the Java compiler so they are called compile-time exceptions. | Unchecked exceptions are not checked by the compiler. These are called runtime exceptions. |
When | Checked exceptions occur at compile time. | Unchecked exceptions occur at runtime. |
Handled by | These types of exceptions can be handled at the time of compilation. | These types of exceptions cannot be caught or handled at the time of compilation, because they get generated by the mistakes in the program. |
Handling | Must be handled in a try-and-catch block, or be thrown by the invoking method | Exception handling semantics are not mandatory. |
Force | Java compiler forces us to handle these exceptions in some manner | A method is not forced by the compiler to declare the unchecked exceptions into the method declaration. |
Hierarchy | They are all subclasses of Exception. | They are all subclasses of RuntimeException. |
Scenario | The checked exception represents a scenario with a higher failure rate | Unchecked Exceptions are mostly programming mistakes. |
Throws clause | The throws clause on a method header must be included for checked exceptions that are not caught and handled in the method. | The throws clause on a method header is not mandatory |
Examples | FileNotFoundException NoSuchFieldException InterruptedException NoSuchMethodException ClassNotFoundException | NoSuchElementException EmptyStackException ArithmeticException NullPointerException ArrayIndexOutOfBoundsException |
Global Exception Handling in Spring Boot
1. What is the need for Global Exception Handling in Spring Boot?
In real-world projects, It’s very important to handle errors correctly and simultaneously provide meaningful error messages to the clients too.
2. How can we make the Error response clear in spring boot exception handling?
- Spring already comes with built-in support for error handling.
- It’s our job to understand and implement it.
3. Annotation used for Spring Boot Error Handling?
In spring boot for global exception handling, we need the following annotations –
- @ControllerAdvice: The @ControllerAdvice annotation handles exceptions globally. It allows you to use the same ExceptionHandler for multiple controllers. This way, we can define how to treat an exception in just one place because this handler will be called whenever the exception is thrown from classes that are covered by ControllerAdvice.
- As the name suggests, is “Advice” for multiple controllers.
- Allows our class to be a global interceptor of exceptions thrown by methods annotated by @RequestMapping.
- @ExceptionHandler: Spring annotation that provides a mechanism to treat exceptions that are thrown during the execution of handlers (Controller operations). This annotation, if used on methods of controller classes, will serve as the entry point for handling exceptions thrown within this controller only.
- @ResponseStatus: Our error responses are always giving us the HTTP status 500 instead of a more descriptive status code. To address this we can annotate our Exception with @ResponseStatus and pass in the desired HTTP response status.
You can also override the existing exception handlers. Spring Boot’s built-in exception class ResponseEntityExceptionHandler has multiple methods that you can override to customize the exception handling further.
Altogether, the most common way is to use @ExceptionHandler on methods of @ControllerAdvice classes so that the exception handling will be applied globally or to a subset of controllers.
@ExceptionHandler and @ControllerAdvice are used to define a central point for treating exceptions and wrapping them up in a class.
Create a spring starter project with dependencies Lombok, MySQL Driver, Spring Data JPA, and Spring Web.
In application.properties
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.jpa.hibernate.ddl-auto=update
@Entity
@Table(name = "emp")
@Data
@NoArgsConstructor
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
}
@Repository
public interface EmployeeRepository extends JpaRepository<Employee, Integer> {
}
@AllArgsConstructor
public class ErrorType {
private String message;
private String code;
private String error;
private String classType;
}
@Getter
public class BusinessException extends RuntimeException {
private static final long serialVersionUID = 1L;
private String message;
private HttpStatus code;
public BusinessException(String message, HttpStatus code) {
super(message); // pass message to RuntimeException()
this.message = message;
this.code = code;
}
}
@Setter
@Getter
@AllArgsConstructor
@NoArgsConstructor
public class EmptyInputException extends RuntimeException {
private static final long serialVersionUID = 1L;
private String message;
private String code;
}
Create a class extending from the ResponseEntityExceptionHandler class and add @ControllerAdvice, and @ResponseStatus annotation on top of the class.
@ControllerAdvice
@ResponseStatus
public class MyControllerAdvice extends ResponseEntityExceptionHandler {
@ExceptionHandler(EmptyInputException.class)
public ResponseEntity<ErrorType> handleEmptyInput(
EmptyInputException emptyInputException) {
return new ResponseEntity<>(
new ErrorType(
emptyInputException.getMessage(),
emptyInputException.getCode(),
"Data Is Empty", "Employee"
),
HttpStatus.BAD_REQUEST);
}
@ExceptionHandler(BusinessException.class)
public ResponseEntity<Map<String, Object>> handleBusinessException(
BusinessException businessException) {
Map<String, Object> exception = new HashMap<>();
exception.put("message", businessException.getMessage());
exception.put("code", businessException.getCode());
return new ResponseEntity<Map<String, Object>>(exception,
businessException.getCode());
}
// We can also change the default exceptions
// For this, class should extend the ResponseEntityExceptionHandler
// Override methods based on requirement
@Override
protected ResponseEntity<Object> handleHttpRequestMethodNotSupported(
HttpRequestMethodNotSupportedException ex,
HttpHeaders headers, HttpStatusCode status,
WebRequest request) {
Map<String, Object> exception = new HashMap<>();
exception.put("message", "Change HTTP Method Type");
exception.put("code", HttpStatus.METHOD_NOT_ALLOWED);
return new ResponseEntity<>(exception,
HttpStatus.METHOD_NOT_ALLOWED);
}
}
@Service
public class EmployeeService {
@Autowired
private EmployeeRepository employeeRepository;
public Employee addEmployee(Employee employee) {
if (employee.getName() == null || employee.getName().isBlank()) {
throw new EmptyInputException("Name Is Empty", "601");
}
Employee savedEmployee = employeeRepository.save(employee);
return savedEmployee;
}
public Employee updateEmployee(Employee employee, Integer id) {
Employee existingEmployee = getEmpById(id);
existingEmployee.setName(employee.getName());
return addEmployee(existingEmployee);
}
public List<Employee> getAllEmployees() {
List<Employee> empList = employeeRepository.findAll();
if (empList.isEmpty()) {
throw new BusinessException("List Is Empty",
HttpStatus.NO_CONTENT);
}
return empList;
}
public Employee getEmpById(Integer id) {
Optional<Employee> employee = employeeRepository.findById(id);
return employee.orElseThrow(() ->
new BusinessException("Employee Not Found",
HttpStatus.NOT_FOUND));
}
public void deleteEmpById(Integer id) {
getEmpById(id); // check whether Employee exist or not
employeeRepository.deleteById(id);
}
}
@Controller
@RequestMapping("/api/emp")
public class EmployeeController {
@Autowired
private EmployeeService employeeService;
@PostMapping
public ResponseEntity<Employee> addEmployee(@RequestBody
Employee employee) {
Employee employeeSaved = employeeService.addEmployee(employee);
return new ResponseEntity<Employee>(employeeSaved,
HttpStatus.CREATED);
}
@GetMapping
public ResponseEntity<List<Employee>> getAllEmployee() {
List<Employee> listOfAllEmps = employeeService.getAllEmployees();
return ResponseEntity.ok(listOfAllEmps);
}
@GetMapping("/{id}")
public ResponseEntity<Employee> findEmployeeById(
@PathVariable Integer id) {
return ResponseEntity.ok(employeeService.getEmployeeById(id));
}
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteEmployeeById(@PathVariable Integer id) {
employeeService.deleteEmpById(id);
return new ResponseEntity<Void>(HttpStatus.ACCEPTED);
}
@PutMapping("/{id}")
public ResponseEntity<Employee> updateEmployeeById(
@RequestBody Employee employee, @PathVariable Integer id) {
Employee savedEmployee =
employeeService.updateEmployee(employee, id);
return new ResponseEntity<Employee>(savedEmployee,
HttpStatus.CREATED);
}
}
API Path:- {{base_url}}/api/emp
{
"name": ""
}
Response:-
{
"code": 601,
"message": "Name Is Empty"
}
API Path:- {{url}}/api/emp/1
Response:-
{
"code": "NOT_FOUND",
"message": "Employee Not Found"
}
4. Give 5 Spring Exceptions that you came across.
- NoSuchBeanDefinitionException
- NoUniqueBeanDefinitionException
- BeanCurrentlyInCreationException
- BeanInstantiationException
- ApplicationContextException
1. NoSuchBeanDefinitionException
This exception occurs when we don’t have any spring beans that we have Autowired in another class. Spring tries to find the definition of the class and tries to inject the dependencies, in this case, the bean is not available in the container therefore it will throw NoSuchBeanDefinitionException.
//@Component
// After commenting the above line (@Component),
// Student class is no longer a bean
public class Student {
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class University {
@Autowired
Student student;
}
// starter class
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Demo1Application {
public static void main(String[] args) {
try {
SpringApplication.run(Demo1Application.class, args);
} catch(Exception e) {
e.printStackTrace();
}
}
}
2. NoUniqueBeanDefinitionException
Assume we have an interface, MyInterface. There are 2 implementation classes for this interface:- MyInterfaceImpl1 & MyInterfaceImpl2. We have a class A that has Autowired the dependency of this interface. Since MyInterfaceImpl1 & MyInterfaceImpl2 have @Component/@Service, therefore, two beans will be created of type MyInterface. So, the framework gets confused about which one class to autowire here.
public interface MyInterface {
}
@Component
public class MyInterfaceImpl1 implements MyInterface {
}
@Component
public class MyInterfaceImpl2 implements MyInterface {
}
@Component
public class Test {
@Autowired
MyInterface myInterface;
}
To resolve this error either use @Qualifier(“BeanName”) or @Primary.
Using @Primary:-
@Component
@Primary
public class MyInterfaceImpl1 implements MyInterface {
}
Using Qualifier:-
@Component
public class Test {
@Autowired
@Qualifier("myInterfaceImpl1")
MyInterface myInterface;
}
What if one class (MyInterfaceImpl2) has @Primary and the Test class contains @Qualifier(“myInterfaceImpl1”) then which will have more preferences?
When both @Primary
and @Qualifier
are used together, @Qualifier
takes precedence over @Primary
.
In this scenario, even though MyInterfaceImpl2
is marked with @Primary
, Spring will inject the bean specified by the @Qualifier
annotation in the Test
class (myInterfaceImpl1
). The @Qualifier
annotation explicitly requests a specific bean by name, overriding the default behavior of @Primary
.
Note:- By default, the bean name is the lowercase of the class name (with the first letter in lowercase). Here, “MyInterfaceImpl1” is a class whereas “myInterfaceImpl1” is a bean.
3. BeanCurrentlyInCreationException
This exception occurs when there is a circular dependency b/w two classes and both are created using constructor injection. In this case, the Student will be searching for the Teacher, and the Teacher will be searching for the Student.
@Component
public class Student {
Teacher teacher;
@Autowired // creating bean through constructor injection
public Student(Teacher teacher) {
this.teacher = teacher;
}
}
@Component
public class Teacher {
Student student;
@Autowired // creating bean through constructor injection
public Teacher(Student student) {
this.student = student;
}
}
There are certain principles to resolve this issue. One of them is using @Lazy in one of those bean creations.
@Component
public class Teacher {
Student student;
@Lazy
@Autowired
public Teacher(Student student) {
this.student = student;
}
}
4. BeanInstantiationException
@Component
public class Sample {
// spring will use this constructor to
// initialize "Sample" class
public Sample() {
throw new RuntimeException(":)");
}
}
5. ApplicationContextException
This exception is related to Spring Boot and it occurs when we miss @SpringBootApplication in the starter class. The framework will try to create a servlet container but without @SpringBootApplication it won’t be able to do that.
If you enjoyed this post, share it with your friends. Do you want to share more information about the topic discussed above or do you find anything incorrect? Let us know in the comments. Thank you!