简体   繁体   English

在IntelliJ IDEA中无法理解Scala中的调试过程

[英]Cannot understand the debug procedure in scala in intellij idea

Today I tried to debug the scala program in intellij idea, I met one phenomenon which I cannot understand. 今天,我尝试以intellij的方式调试scala程序,遇到了一种我无法理解的现象。 The program is as follows: 该程序如下:

import java.io._
import scala.collection.mutable.ArrayBuffer

class Person(val name: String) extends Serializable {
  val friends = new ArrayBuffer[Person]
  // OK—ArrayBuffer is serializable
  def description = name + " with friends " +
    friends.map(_.name).mkString(", ")
}

object TestSec08 extends App{
  val fred = new Person("Fred")
  val wilma = new Person("Wilma")
  val barney = new Person("Barney")
  fred.friends += wilma
  fred.friends += barney
  wilma.friends += barney
  barney.friends += fred

  val out = new ObjectOutputStream(new FileOutputStream("test.obj"))
  out.writeObject(fred)
  out.close()
  val in = new ObjectInputStream(new FileInputStream("test.obj"))
  val savedFred = in.readObject().asInstanceOf[Person]
  in.close()

  savedFred.description
  savedFred.friends.map(_.description)
}

Then I debug it from the first line, when it goes to the 4th line, which is "fred.friends += wilma", in my sense, it should continue to the next line-"fred.friends += barney". 然后我从第一行调试它,到第四行,即“ fred.friends + = wilma”,就我而言,它应该继续到下一行-“ fred.friends + = barney”。 But instead of that, it goes back to the first line which confused me very much. 但是相反,它回到了第一行,这让我非常困惑。 Can anybody explain the reason why it happens like this? 有人能解释为什么会这样吗? Thanks in advance! 提前致谢!

val declaration in a class body is implemented in Scala as a private field and a getter. 类主体中的val声明在Scala中实现为私有字段和getter。

Look at the decompiled bytecode of the TestSec08 initialization: 查看TestSec08初始化的反编译字节码:

/* Initializing private field `fred` */
     0: aload_0
     1: new           #95                 // class Person
     4: dup
     5: ldc           #102                // String Fred
     7: invokespecial #105                // Method Person."<init>":(Ljava/lang/String;)V
    10: putfield      #78                 // Field fred:LPerson;
/* Initializing private field `wilma` */
    13: aload_0
    14: new           #95                 // class Person
    17: dup
    18: ldc           #107                // String Wilma
    20: invokespecial #105                // Method Person."<init>":(Ljava/lang/String;)V
    23: putfield      #80                 // Field wilma:LPerson;
/* Initializing private field `barney` */
    26: aload_0
    27: new           #95                 // class Person
    30: dup
    31: ldc           #109                // String Barney
    33: invokespecial #105                // Method Person."<init>":(Ljava/lang/String;)V
    36: putfield      #82                 // Field barney:LPerson;
    39: aload_0
/* Calling getter for field `fred` */
    40: invokevirtual #111                // Method fred:()LPerson;
/* Getting the array of fred's friends */
    43: invokevirtual #115                // Method Person.friends:()Lscala/collection/mutable/ArrayBuffer;
    46: aload_0
/* Calling getter for field `wilma` */
    47: invokevirtual #117                // Method wilma:()LPerson;
/* Adding wilma to fred's friends */
    50: invokevirtual #123                // Method scala/collection/mutable/ArrayBuffer.$plus$eq:(Ljava/lang/Object;)Lscala/collection/mutable/ArrayBuffer;

If you also look at the line number tables, you'll notice that the start of this method and the fred getter correspond to the same line in the source code: val fred = new Person("Fred") . 如果您还查看行号表,则会注意到此方法的开始和fred getter对应于源代码中的同一行: val fred = new Person("Fred")

So when the debugger stops at the line val fred = new Person("Fred") for the first time, it is initializing the private field with new Person("Fred") , and when it goes to that line after that, it is executing the synthesized getter method. 因此,当调试器首次在val fred = new Person("Fred")行停止时,它将使用new Person("Fred")初始化私有字段,然后在此之后转到该行执行合成的吸气剂方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM