Ones is for the case when the exception was implicitly caught and needs to get rethrown (note the ATHROW
at the end)
L15
LINENUMBER 155 L15
ALOAD 4: out
INVOKEVIRTUAL FileOutputStream.close () : void
L14
LINENUMBER 157 L14
ALOAD 6
ATHROW
The other for when no exception is thrown:
L19
LINENUMBER 155 L19
ALOAD 4: out
INVOKEVIRTUAL FileOutputStream.close () : void
If you look at the top, you see
TRYCATCHBLOCK L0 L1 L1
Those labels are something like for where to jump for the catch and where to jump for the finally. Catch leaves the thrown exception on the top of the stack (again, ATHROW). Inspecting the stack to see if the top member is an exception is a lot more expensive (and harder/impossible; the stack isn't typed) than just duplicating the code.