Leaving aside the religious debate about Checked vs Runtime exceptions, there are times where due to poorly constructed libraries, dealing with checked examples can drive you insane.
Consider this snippet of code which you might want to write:
For it to compile you need to catch the exception which leaves you with this code:
Although this compiles, the IOException has effectively been swallowed. The user of this method should be informed that an Exception has been thrown.
To address this you could wrap the IOException in a generic RuntimeException as below:
This code does throw an Exception but not the actual IOException which was intended to be thrown by the code. It's possible that those in favour of RuntimeExceptions only would be happy with this code especially if the solution could be refined to created a customised IORuntimeException. Nevertheless the way most people code, they would expect their method to be able to throw the checked IOException from the File.createTempFile method.
The natural way to do this is a little convoluted and looks like this:
From inside the lambda, you would have to catch the IOException, wrap it in a RuntimeException and throw that RuntimeException. The lambda would have to catch the RuntimeException unpack and rethrow the IOException. All very ugly indeed!
In an ideal world what we need is to be able to do is to throw the checked exception from within the lambda without having to change the declaration of computeIfAbsent. In other words, to throw a check exception as if it were an runtime exception. But unfortunately Java doesn't let us do that...
That is not unless we cheat! Here are two methods for doing precisely what we want, throwing a checked exception as if it were a runtime exception.
Method 1 - Using generics:
Note that we have create and thrown an IOException without it being declared in the main method.
Method 2 - Using Unsafe:
Again we have managed to throw an IOException without having declared it in the method.
Whichever method you prefer we are now free to write the original code in this way:
The doThrow() method would obviously be encapsulated in some utility class leaving your code in createTempFileForKey() pretty clean.