如何使用新TryAPI 将以下Java代码转换为Scala ?
public byte[] deflate(byte[] data) {
ByteArrayOutputStream outputStream = null;
GZIPOutputStream gzipOutputStream = null;
try {
outputStream = new ByteArrayOutputStream();
gzipOutputStream = new GZIPOutputStream(outputStream);
gzipOutputStream.write(data);
return outputStream.toByteArray();
catch (Exception e) {
...
} finally {
if (gzipOutputStream != null) gzipOutputStream.close();
}
}
Run Code Online (Sandbox Code Playgroud)
Scala版本应该是这样的......
def deflate(data Array[Byte]): Try[Array[Byte]] = Try {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream()
new GZIPOutputStream(outputStream).write(data)
outputStream.toByteArray
}
Run Code Online (Sandbox Code Playgroud)
...但是如何实现Java的finally等效?
Scala的TryAPI不应该直接等同try-catch-finally于Java中的构造.的确,它应该是什么原因?Scala也有内置try-catch-finally构造.您可以像在Java中一样直接使用它.Try需要组合可能失败的多个操作时需要.
实际上,您提出了更复杂的问题 - 资源管理.事实上,你的代码应该是这样的:
try (ByteArrayOutputStream os = new ByteArrayOutputStream(data);
GZIPOutputStream gzos = new GZIPOutputStream(os)) {
gzipOutputStream.write(data);
return outputStream.toByteArray();
} catch (Exception e) {
...
}
Run Code Online (Sandbox Code Playgroud)
Java中的"try-with-resources"语言功能会自动关闭您在括号中指定的所有资源try.
不幸的是,Scala在库或语言中没有它的直接等价物.但是因为Scala更具表现力,你可以手动编写这个结构或使用第三方库,我建议使用它scala-arm.有关更多信息,请参阅以下链接
由于 Try {} 块永远不会抛出异常,因此不需要 finally 语句。此外,对于这种特殊情况,您可能应该使用 scala-arm,就像其他海报所建议的那样。
但是您可以轻松地向 Try 添加一个 finally 方法,该方法在成功或失败的情况下执行副作用。
像这样的东西:
implicit class TryHasFinally[T](val value:Try[T]) extends AnyVal {
import scala.util.control.NonFatal
def Finally(action: => Unit) : Try[T] =
try {
action;
value
} catch {
case NonFatal(cause) => Failure[T](cause)
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,本着所有 Try 方法的精神,如果您的操作抛出非致命异常,则不会抛出异常,而只是将其捕获为失败。
你会像这样使用它:
import java.io._
import java.util.zip._
def deflate(data: Array[Byte]): Try[Array[Byte]] = {
var outputStream : ByteArrayOutputStream = null
Try {
outputStream = new ByteArrayOutputStream()
new GZIPOutputStream(outputStream).write(data)
outputStream.toByteArray
} Finally {
outputStream.close()
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,您不必在Finally 中检查null,因为如果由于某种深不可测的原因输出流为null,您将只会得到一个Failure(NullPointerException)。此外,如果 close 抛出 IOException,您只会得到一个 Failure(IOException)。
| 归档时间: |
|
| 查看次数: |
2152 次 |
| 最近记录: |