Scala';s参数字段和构造函数参数

Scala';s参数字段和构造函数参数,scala,Scala,我知道参数化字段(如下例中的x)的行为与正常字段类似;因此,您可以在方法中引用它们: class Test(val x: Int) { // x is a parametric field override def toString = "Test: " + x; } 但是,如果删除关键字val,代码仍会编译(并且查看.class输出,x仍然是该类的成员)。所以我想知道,参数字段(即上面的valx:Int)和构造函数参数(x:Int)之间有什么区别 (有了Java在我的脑后,我会期望像x这

我知道参数化字段(如下例中的
x
)的行为与正常字段类似;因此,您可以在方法中引用它们:

class Test(val x: Int) { // x is a parametric field
  override def toString = "Test: " + x;
}
但是,如果删除关键字
val
,代码仍会编译(并且查看
.class
输出,
x
仍然是该类的成员)。所以我想知道,参数字段(即上面的
valx:Int
)和构造函数参数(
x:Int
)之间有什么区别


(有了Java在我的脑后,我会期望像
x
这样的构造函数的范围不包括
toString
这样的方法)

如果没有
val
关键字,您的代码类似于:
类测试(private[this]val x:Int){…
。因此,
x
在整个类中可用,但在外部不可用


您的问题中没有提到它,但它可能也很有用:在
案例类中,默认修饰符是
val
。因此,
case-class-Test(x:Int){…}
相当于
case-class(val x:Int){…}

构造函数参数有效地成为
private[this]
字段,但前提是在至少一个方法中引用。否则,不会在类中生成字段

例如:

class Foo(i: Int) {
  println(i)
}
变成

$ javap -private Foo
Compiled from "Foo.scala"
public class Foo extends java.lang.Object implements scala.ScalaObject{
    public Foo(int);
}
$ javap -private Bar
Compiled from "Bar.scala"
public class Bar extends java.lang.Object implements scala.ScalaObject{
    private final int i;
    public void baz();
    public Bar(int);
}
但是

变成

$ javap -private Foo
Compiled from "Foo.scala"
public class Foo extends java.lang.Object implements scala.ScalaObject{
    public Foo(int);
}
$ javap -private Bar
Compiled from "Bar.scala"
public class Bar extends java.lang.Object implements scala.ScalaObject{
    private final int i;
    public void baz();
    public Bar(int);
}

当然,等于减去案例类
拥有的所有其他内容。:-)@事实上,我还没有精确到这一点,因为你纠正的错误并不是一个真正的错误我相信
x
如果在至少一个方法中引用了它,那么它仍然会成为一个成员,不管它是否以
val
作为前缀。