Why in Java can we catch an Exception even if it is not thrown, but we can\'t catch it\'s subclass (except for \"unchecked\" RuntimeExceptions and
Simply Java assumes that any code line can throw a generic Exception or Throwable, ie. OutOfMemoryException which is an Error rather an Exception. Same applies for NPE.
IOException is a specific exception that can be thrown only by managed code, so if you don't have I/O calls in your catch block your compiler that there is no chance to catch it.
Just to compare to C# world, in C# such code would be compiled but would be a conceptual mistake since if you don't do anything you don't reach the catch block. A tool such as ReSharper can warn you about that.