Community
Participate
Working Groups
Consider the following code sequence. import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.SocketException; import java.net.UnknownHostException; public class maskedException { private DatagramSocket _socket = null; maskedException() throws Exception { try { _socket = new DatagramSocket( 5000,InetAddress.getLocalHost() ); } catch (SocketException e) { throw new Exception(); } catch (UnknownHostException e) { throw new Exception(); } ****** catch (IOException e) { throw new Exception(); } } The compiler issues a diagnostic stating "Catch block is hidden by another one in the same try statement" The diagnostic is only triggered when the catch blocks throw a new exception. Any other code in the catch blocks does not cause a problem. The code sequence is normal in the sense that most specific exceptions are caught first and most general exceptions last. This code does not generate a diagnostic with either the JBuilder compiler or the Sun compiler from JDK 1.3.1-04.
It is only an extra warning we produce. If you did write your code in 2 nested try statements, wouldn't it report an error with the other compilers ? If no, then I agree we have a bug. But I guess it does, and we give you an advanced warning for this scenario (I guess that for the catch block to be reachable, a non declared exception would need to be thrown, which might indicate a binary compatibility issue: the constructor for DatagramSocket you are using to compile against isn't the same that you run against). Doesn't this fail to compile with other compilers ? try { try { _socket = new DatagramSocket( 5000,InetAddress.getLocalHost() ); } catch (SocketException e) { throw new Exception(); } catch (UnknownHostException e) { throw new Exception(); } catch (IOException e) { throw new Exception(); }
Humm, actually, I take my previous comment back. We seem to have a bug. The nested scenario doesn't report a problem. You are absolutely right, we should not complain.
On the other side of the coin, though, it turns out that in all three cases where we had this kind of code sequence, using the Sun JDK 1.3.1-04 and your M1 compiler the IOException was not being thrown. Thus at least this prompted us to remove some obselete code. It might be useful in fact if the compiler could recognize that the last exception in the chain could not be caught because it was not being thrown, only derived exceptions that were caught. BTW the code snippet you sent me compiles OK on JBuilder and the Sun compiler.
Actually, I think our behavior is correct. The reason why the nested case compiles ok (even with our compiler) is due to the fact that Exception(s) are rethrown in the catch block clauses. These exception are thus to be handled by the outermost try/catch. This becomes obvious with some slight change in your code (javac will diagnose that IOException isn't reachable - like Eclipse compiler). void maskedException() throws Exception { boolean broken = false; try { try { _socket = new DatagramSocket(5000, InetAddress.getLocalHost()); } catch (SocketException e) { broken = true; } catch (UnknownHostException e) { broken = true; } } catch (IOException e) { broken = true; } if (broken) throw new Exception(); } You can observe that this one is an error, as opposed to the advanced warning notification we gave you in the flatten case (and you can turn off this extra warning: Window>Preferences>Java>Compiler>Hidden catch blocks>Ignore). Is it ok to close then ?
Closing, please reopen if you feel we are still wrong.