欺骗异常 – Java 8 Lambdas
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了欺骗异常 – Java 8 Lambdas,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3450字,纯文字阅读大概需要5分钟。
内容图文
抛开检查异常和运行时异常的宗教争论,有很多次那些处理检查异常的例子的可怜构造类库就能让你发疯。
考虑下面你可能想要写的一小段代码:
public
void createTempFileForKey(String key) {
Map<String, File> tempFiles =new ConcurrentHashMap<>();
//不编译,因为抛出了IOException
tempFiles.computeIfAbsent(key, k -> File.createTempFile(key, ".tmp"));
}
为了正常编译你需要捕获这个异常。代码如下:
public
void
createTempFileForKey(String key) {
Map<String, File> tempFiles = new ConcurrentHashMap<>();
tempFiles.computeIfAbsent(key, k -> {
try {
return File.createTempFile(key, ".tmp");
}catch(IOException e) {
e.printStackTrace();
returnnull;
}
});
}
尽管这段代码能正常编译,实际上IOException已经被吞掉了。这个方法的用户应该被通知已经抛出了一个异常。
为了解决这个你可以把IOException包装成一个范型的RuntimeException,如下:
public
void
createTempFileForKey(String key) throws RuntimeException {
Map<String, File> tempFiles = new ConcurrentHashMap<>();
tempFiles.computeIfAbsent(key, k -> {
try {
return File.createTempFile(key, ".tmp");
}catch(IOException e) {
thrownew RuntimeException(e);
}
});
}
这段代码抛出了一个异常,但不是这段代码应该自然抛出的那个IOException。对那些支持RuntimeExceptions的人来说, 这段代码可能会让他们高兴。尤其解决方案是重新定义了一个自定义的IORuntimeException.不过大多数人编码的方式是,他们期望他们的方法能从File.createTempFile方法抛出检查时IOException.
这样做的自然方式有一点复杂,像这样:
public
void
createTempFileForKey(String key) throws IOException{
Map<String, File> tempFiles = new ConcurrentHashMap<>();
try {
tempFiles.computeIfAbsent(key, k -> {
try {
return File.createTempFile(key, ".tmp");
} catch (IOException e) {
thrownew RuntimeException(e);
}
});
}catch(RuntimeException e){
if(e.getCause() instanceof IOException){
throw (IOException)e.getCause();
}
}
}
从lamabda内部,你必须捕获异常,把它包装成一个RuntimeException并抛出这个RuntimeException.lambda必须捕获这个RuntimeException解包并重新抛出这个IOException.所有这些的确非常丑陋。
理想的做法是在lamabda内部抛出一个检查异常,不用改变computeIfAbsent的声明。换句话说,如果是一个运行时异常就抛出一个检查异常。但不幸的是Java不会让我们这样做。
除非我们作弊。下面的两个方法精确的做到了我们想要的,假如是一个运行时异常就抛出一个检查异常。
方法1—-用范型
public
static
void
main(String[] args){
doThrow(new IOException());
}
staticvoid doThrow(Exception e) {
CheckedException.<RuntimeException> doThrow0(e);
}
static <E extends Exception>
void doThrow0(Exception e) throws E {
throw (E) e;
}
注意我们创建并抛出了一个没有在main方法里声明的IOException。
方法2—用Unsafe类:
public
static
void
main(String[] args){
getUnsafe().throwException(new IOException());
}
privatestatic Unsafe getUnsafe(){
try {
Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafe.setAccessible(true);
return (Unsafe) theUnsafe.get(null);
} catch (Exception e) {
thrownew AssertionError(e);
}
}
我们又一次设法抛出了一个没有在其方法里声明的IOException。不管你更喜欢哪个方法,我们现在可以用这种方式自由地写原始代码。
public
void
createTempFileForKey(String key) throws IOException{
Map<String, File> tempFiles = new ConcurrentHashMap<>();
tempFiles.computeIfAbsent(key, k -> {
try {
return File.createTempFile(key, ".tmp");
} catch (IOException e) {
throw doThrow(e);
}
});
}
private RuntimeException doThrow(Exception e){
getUnsafe().throwException(e);
returnnew RuntimeException();
}
privatestatic Unsafe getUnsafe(){
try {
Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafe.setAccessible(true);
return (Unsafe) theUnsafe.get(null);
} catch (Exception e) {
thrownew AssertionError(e);
}
}
doThrow()方法明显的包装在了一些工具类里,这样可以使你在createTempFileForKey()方法中的代码更加简洁。
原文:http://blog.csdn.net/supercrsky/article/details/45891741
内容总结
以上是互联网集市为您收集整理的欺骗异常 – Java 8 Lambdas全部内容,希望文章能够帮你解决欺骗异常 – Java 8 Lambdas所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。