This:
myList.add(new FileNotFoundException());
compiles because FileNotFoundException
is an IOException
, just as it is an Exception
, so it satisfies the bound of myList
.
This:
myList.add(new Exception());
does not compile because the compiler does not know what exact type the list is (it doesn't check what was assigned to the varaible, it only looks at its declared type), so it doesn't know if the list assigned to it has a type that matches a super type of IOException
, but not Exception
.
This would happen is there was an intermediate class in the hierarchy between Exception
and IOException
. If the list actually had that type, Exception
may not match the bound of the actual list assigned to myList
.
The compiler doesn't check the complete class hierarchy nor what was assigned. It only does a basic check that always avoids runtime errors.
This is also true more generally where "logically" there is no code path that will cause an error, but the compile still fails.
? super IOException
I am specifying an Lower bound that the List can contain only the super classes ofIOException
and it cannot contain any sub class of it. So the compiler should allow to addException
object and give error while addingFileNotFoundException
– Skulk