Any exception that is thrown while closing a resource is added to the list of suppressed exceptions of the exception thrown while opening a resource (or thrown from the try block.)
That said, suppressed exceptions do not prohibit the program from continuing its normal execution.
The close method for D2 wasn't called ('Closing device D2' was not printed), because the constructor method of D2 did not fully finish. Is this assumption correct?
if the program throw new RuntimeException in the close() method when creating Device d1, wouldn't it terminate the program with this RuntimeException?
not sure why throw new RuntimeException is ignored even though it should be executed right after "Closing device D1" statement.
No, the program doesn't throw any exception while creating Device d1. There is no exception during new Device("D1"). Device D1 is created successfully. The program throws an IOException when creating d1 because new Device("D2") throws an IOException. When this exception is thrown, the try-with-resources mechanism will try to close Device D1 and that is when a RuntimeException is thrown.
Please go through the explanation carefully, it doesn't say that new RuntimeException is ignored. The explanation says it is added to the list of suppressed exceptions.