Aside from the religious arguments that check for anomalies and run-time anomalies, there are a number of poor structural libraries that deal with examples of checking anomalies that can drive you crazy.
Consider a small piece of code that you might want to write:
publicvoid createTempFileForKey(String key) { Map<String, File>=new ConcurrentHashMap<>(); //不编译,因为抛出了IOException tempFiles.-> File.".tmp"));}
For normal compilation You need to catch this exception. The code is as follows:
publicvoidcreateTempFileForKey(String key) { new ConcurrentHashMap<>(); tempFiles.computeIfAbsent(key, k -> { try { return".tmp"); }catch(IOException e) { e.printStackTrace(); returnnull; } });}
Although this code compiles normally, IOException has actually been swallowed. The user of this method should be notified that an exception has been thrown.
To solve this, you can wrap the ioexception into a generic runtimeexception, as follows:
publicvoidcreateTempFileForKeythrows RuntimeException { new ConcurrentHashMap<>(); tempFiles.computeIfAbsent(key, k -> { try { return".tmp"); }catch(IOException e) { thrownew RuntimeException(e); } });}
This code throws an exception, but not the ioexception that the code should naturally throw. For those who support runtimeexceptions, this code may make them happy. In particular, the solution is to redefine a custom ioruntimeexception. But most people encode the way they expect their methods to be ioexception from the File.createtempfile method when they throw a check.
The natural way to do this is a little more complicated, like this:
Public void Createtempfileforkey(String key)throwsioexception{map<string, file> tempfiles =NewConcurrenthashmap<> ();Try{Tempfiles.computeifabsent (key, K, {Try{returnFile.createtempfile (Key,". tmp"); }Catch(IOException e) {Throw NewRuntimeException (e); } }); }Catch(RuntimeException e) {if(E.getcause ()instanceofIOException) {Throw(IOException) E.getcause (); } }}
From inside the LAMABDA, you must catch the exception, Wrap it into a runtimeexception and throw this runtimeexception.lambda must capture this runtimeexception unpack and re-throw the IOException. All this is really ugly.
The ideal approach is to throw a check exception inside LAMABDA without changing the computeifabsent declaration. In other words, if it is a run-time exception, a check exception is thrown. But unfortunately Java won't let us do that.
Unless we cheat. The following two methods do exactly what we want, and if a runtime exception throws a check exception.
Method for the use of the norm type
publicstaticvoidmain(String[] args){ doThrow(new IOException()); } staticvoid doThrow(Exception e) { CheckedException.<RuntimeException> doThrow0(e); } static <E extends Exception> voidthrows E { throw (E) e; }
Note that we created and thrown a ioexception that was not declared in the main method.
Method 2-Use the unsafe class:
public static void main (string[] args) {Getunsafe (). ThrowException ( new IOException ()); } private static Unsafe getunsafe () {try {Field Theunsafe = Unsafe.class.getDeclaredField ( "Theunsafe" ); Theunsafe.setaccessible (true ); return (Unsafe) Theunsafe. get (null ); } catch (Exception e) {throw new assertionerror (e); } }
Once again we managed to throw out a ioexception that was not declared in its method. No matter which method you prefer, we can now freely write the original code in this way.
Public void Createtempfileforkey(String key) throws ioexception{map<string, file> tempfiles =NewConcurrenthashmap<> (); Tempfiles.computeifabsent (key, K, {Try{returnFile.createtempfile (Key,". tmp"); }Catch(IOException e) {ThrowDothrow (e); } }); }PrivateRuntimeExceptionDothrow(Exception e) {Getunsafe (). ThrowException (e);return NewRuntimeException (); }Private StaticUnsafeGetunsafe(){Try{Field Theunsafe = Unsafe.class.getDeclaredField ("Theunsafe"); Theunsafe.setaccessible (true);return(Unsafe) Theunsafe.Get(NULL); }Catch(Exception e) {Throw NewAssertionerror (e); } }
The Dothrow () method is clearly packaged in some tool classes, which will make your code in the Createtempfileforkey () method more concise.
Spoofing Exception –java 8 Lambdas