这里的答案非常好,但是我正在通过探索字节码来解决这个问题。当您申请javap
一个类时,它会打印出所传递的类的包、受保护和公共字段和方法。我创建了一个类 Person.scala 并用以下代码填充它。
class Person(name: String, age: Int) {
def say = "My name is " + name + ", age " + age
}
class PersonVal(val name: String, val age: Int) {
def say = "My name is " + name + ", age " + age
}
class PersonVar(var name: String, var age: Int) {
age = happyBirthday(5)
def happyBirthday(n: Int) = {
println("happy " + n + " birthday")
n
}
}
用它编译代码后,scalac Person.scala
会生成三个名称为Person.class, PersonVal.calass , PersonVar.cass
. 通过运行javap
这些类文件中的每一个,我们可以看到结构将如何:
>>javap Person.class
Compiled from "Person.scala"
public class Person {
public java.lang.String say();
public Person(java.lang.String, int);
}
在这种情况下,它没有为 Person 创建任何类变量,因为它既没有使用 val 也没有使用 val 声明,因此名称和年龄只能在构造函数中使用。
>>javap PersonVal.class
public class PersonVal {
public java.lang.String name();
public int age();
public java.lang.String say();
public PersonVal(java.lang.String, int);
}
在这种情况下,它有三个成员,两个用于输入构造函数,一个用于我们在构造函数中声明的成员。但是,我们没有任何输入构造函数的设置器,因此我们无法更改值。
>>javap PersonVar.class
public class PersonVar {
public java.lang.String name();
public void name_$eq(java.lang.String);
public int age();
public void age_$eq(int);
public int happyBirthday(int);
public PersonVar(java.lang.String, int);
}
它与 PersonVal 示例相同,但我们可以在这种情况下使用这些variable_$eq
方法更改值。它只是一个缩短版本variable =