Spoofing Exception –java 8 Lambdas

Source: Internet
Author: User

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

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.