Just to add one more thing...
The way the compiler knows which are checked and which are unchecked, is that checked exceptions must be subclasses of Exception, but must NOT be of type RuntimeException (in other words, it can't be a subclass of RuntimeException).
Object
|_ Throwable
|_Error <-- not checked
|_Exception <-- checked
|RuntimeException <-- not checked
But you also need to know that there are other things that are "Throwable" (which means they can be "caught") even though not checked by the compiler. Anything that subclasses Throwable (so, Error, Exception, RuntimeException and all their subtypes) can be caught, declared, thrown, whatever -- but only the ones that subclass Exception but do NOT subclass RuntimeException are the ones that must be "handled or declared".
Be sure you know that AssertionErrors are Errors and not Exceptions, but that means they are still Throwables, and thus can be caught... even though
you should NEVER catch them. You're expected to clearly understand all these implications.
And don't forget that you can always create your own exceptions -- both checked and unchecked -- even though you're discouraged from making your own UNchecked exceptions. Still legal, though.
cheers,
Kathy