我正在尝试解决“不耐烦的 Scala”一书给出的问题,该书要求将 java 的 BufferedInputStream 作为特征实现。这是我的实现,

trait Buffering {
    this:InputStream =>
        private[this] val bis = {
            new JavaBufferedInputStream(this)
        }
        override def read = bis.read
        override def read(byte:Array[Byte], off:Int, len:Int) = bis.read(byte, off, len)
        override def available = bis.available
        override def close() {
            bis.close
        }
        override def skip(n:Long) = bis.skip(n)
}

def main(args:Array[String]) {
    val bfis = new FileInputStream(new File("foo.txt")) with Buffering
    println(bfis.read)
    bfis.close
}

但这给了我一个 java stackoverflow 错误,那么它有什么问题呢?谢谢!

最佳答案

看起来您遇到了堆栈溢出,而您不希望出现堆栈溢出。解决这些问题的关键是查看堆栈跟踪的重复循环。它通常指向重复分配帧的内容。在这里它会显示类似的东西:

at C.Buffering$class.read(C.scala:12)
at C.C$$anon$1.read(C.scala:23)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:256)
at java.io.BufferedInputStream.read(BufferedInputStream.java:317)
at C.Buffering$class.read(C.scala:12)
at C.C$$anon$1.read(C.scala:23)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:256)
at java.io.BufferedInputStream.read(BufferedInputStream.java:317)
at C.Buffering$class.read(C.scala:12)

因此,从下到上阅读,看起来您的 read(byte, ...) 正在调用 bis.read(byte, ...),后者正在调用 BufferedInputStream.read,然后又再次调用您的 read(byte, ...)

看起来 new BufferedInputStream(this) 正在调用底层 read 上的 InputStream 但由于底层 this 是您的对象,然后将调用委托(delegate)给 bis 我们有无限递归。

我猜作者希望您使用 abstract override 可堆叠修改模式,您可以在其中使用 super 来引用正确的 read 方法。

关于scala - 在 Scala 中使用 bufferedInputStream 作为特征时的 Stackoverflow,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10169016/

10-16 10:37