- Runtime exceptions. These don't need to be caught or declared by Java code, but you can generally avoid them by making sure you have null reference checks and using iterators for collections.
- Exceptions that you throw yourself. You know you're throwing these and the odds are that you want the caller to handle them (if you're using exceptions for intraprocedural flow control, then you're an idiot). So advertise them on your method. Done.
- Exceptions thrown by methods that you call. These are all advertised by those methods and checked by the compiler (or your IDE), so there's no excuse for not knowing that they're expected.
This stuff isn't hard. You know at every call site what the possible exceptions are, and you know this because the compiler won't let you explicitly throw or fail to handle any exceptions in your methods. The exceptions that a method can throw are in the JavaDoc and are checked at compile time, so you'll get a compile error if you don't either handle or advertise the exception.
Good error handling is one of the key things that differentiates good developers from bad. If it's something that you find hard, in a language that goes out of its way to make it easy, then you might want to consider other careers.