Instead of throwing new Exception(\"Some message\", maybeSomeCause), which means that all callers of my method will need to catch Exception (which can include Runti
Most core exceptions are too specialized to be used directly, unless you're duplicating existing functionality in the core libs. For instance, you'll probably never need to create an an instance of UnknownHostException; if host resolution fails, the InetAddress or SocketFactory method you called would have already created and thrown the exception.
The only exceptions I've found to be generally usable are IOException, IllegalArgumentException, IllegalStateException, and UnsupportedOperationException.
IOException - All problems with interfaces, networking, and hard drive access fall under this. If you're writing code to access external data or hardware, you should be using this. For instance, if you're implementing an API to access a certain type of network device, you can make a MyDeviceException subclass to be thrown when the device returns an error status or does something strange. There are also some cases where you want to catch an IOException from one or more low-level library calls and wrap it in another IOException with a higher-level message, such as a connectivity check throwing a "Device not available" exception caused by a "Request timed out" exception.
IllegalArgumentException - Any parameter checks should throw this. For example, a negative integer for a size parameter, or an unexpected null. This is an unchecked exception, but I recommend documenting it anyway to make the method preconditions more clear. You can find lots of examples in the core libs.
IllegalStateException - You can use this when the method parameters are valid, but some internal data or functionality required by the method is unavailable, and there isn't a more appropriate checked exception (like IOException). It's often better to design things so that this isn't necessary.
UnsupportedOperationException - If you make a subclass of something and one of the superclass methods is conceptually invalid for it, override it and throw one of these. Guava uses this for its immutable collection classes, since Java's collection interfaces aren't designed to support immutability. This tends to be a sign of bad design in the superclass. Don't use it if just doing nothing or returning null/empty would be an appropriate and unsurprising result.