Exception handling in Java allows programs to gracefully handle errors and unexpected conditions. There are two main types of exceptions - checked exceptions that must be declared and handled, and unchecked exceptions that do not require declaration. The try-catch block is used to catch and handle exceptions, while the finally block always executes to clean up resources regardless of whether an exception occurred or not. Custom exceptions can also be created to generate application-specific error messages.