Try subclassing Z from RuntimeException instead of Exception. The code will compile.
As you know, in
Java RuntimeException and its subclasses are not checked, i.e. can be thrown without being caught.
So a normal code can throw a runtime exception for example:
int[] a = new int[5];
a[5] = 6;
or
int b = 0;
int d = 1 / b;
Both code can throw a RuntimeException which needn't be caught.
But you can catch a RuntimeException for sure by
try {
int b = 0;
int d = 1 / b
}
catch (RuntimeException e) {
// handling the exception
}
Notice that any normal code even if that doesn't throw a checked exception - an exception which is not a subclass of RuntimeException - can be put in a try block followed by a catch (RuntimeException e) {} block. But since Exception is a superclass of RuntimeException, and since everything caught by X can be caught by the superclass of X, we can put any code in a try block followed by a catch (Exception e) {} block.
Notice that Z is not a superclass of RuntimeException (nor a subclass) , so the above argument is not valid for it. The only justification for catching it is the possiblity of it be thrown and this is only possible if the code throws it explicity or call a method that declare that it may throw it.
Notice that an empty code is a normal code
(if you read about how compilers work you find a rule a BNF rule like
statement -> IFStatement | ForStatement | CompoundStatement
CompoundStatement -> { statement* } // a repetition of 0 or more statement...
)
So in theory an empty statement is a statement, and any statement is allowed to throw a RuntimeExecption without declaring so, so the codes is valid.
In practice any compiler ignore this statement entirely (with its try and catch). Moreover, I think if the compiler can make sure that the a block can't throw any RuntimeException, it will ignore all the relevant catchs...
Hope this helps