Exceptions and Generics
Exceptions
Throwable
Throwable has two subclasses: Exception and Error
The Error class represents serious errors that are generally not recommended to be caught with catch in our programs. We can only optimize Error by optimizing code. When Error occurs, JVM generally chooses to terminate the thread.
The Exception class has two subclasses: Checked Exception and Unchecked Exception.
Checked Exception indicates that the exception will be checked at compile time. If the exception is not caught with catch or declared with throws, it won’t pass compilation. This includes IOException, ClassNotFoundException.
Unchecked Exception indicates that it won’t be checked at compile time. It includes RuntimeException and its subclasses, such as NullPointerException, ArrayIndexOutOfBoundsException, and ClassCastException that may occur during forced type conversion.
try-catch-finally
finally is used to close input/output streams and database connections.
| |
If return is executed in the try block, finally will still be executed. The num value is modified to 30, but the returned value is still 20. This is because when return is executed in the try block, the return value has already been determined.
If System.exit() is executed in try or catch, then the finally block will not execute.
How to Handle Multiple Exceptions?
- Multiple catch blocks separately catch different exceptions.
| |
| |
- One catch block catches the parent class of these exceptions.
It’s best to write catch blocks for subclass exceptions first, so they won’t be uniformly treated as parent class exception handling. You can add some logging in catch blocks to facilitate problem troubleshooting.
throw and throws
throw is for actively throwing exceptions.
| |
throws is placed in the function signature to declare which exceptions this method might throw, letting the caller handle them. If the caller doesn’t use catch to handle them, they will be thrown layer by layer up the call stack until reaching the main function.
| |
Generics
Generic Methods
| |
Generic Classes
A generic class can accept properties of multiple types.
| |
Generic Interfaces
When implementing the interface, specify a concrete class.
| |
You can also not specify a concrete class when implementing the interface, allowing the specific type to be specified when creating instances of the GeneratorImpl class.
| |
Bounded Types
| |
Bytecode Files
- Type Erasure: During compilation, generic type parameters are erased and usually replaced with Object
- Bridge Methods: Subclasses may override generic methods from parent classes. To ensure subclass methods can correctly override parent class methods, the compiler generates bridge methods.
| |
Obviously, the final output will be “Child Set”. But this actually calls the bridge method in the subclass that we cannot see.
| |
- Generic Signatures: Generic information for generic classes, methods, and fields is stored in bytecode in a special format. This information can be obtained through reflection APIs (such as getGenericType()).