Scala Fields in Classes

Scala Fields in Classes

private var定义field

class Student(name: String, age: Int) {

  private var _id: Int = name.hashCode

  def id: Int = _id //reader method

  def id_=(newId: Int): Unit = _id = newId //writer method

  def sayHi(): String = {
    "my name is " + name + ",my age is " + age
  }
}

在类的内部定义一个这样的属性字段private var _id: Int = name.hashCode。反编译如下,

C:\WorkSpace5-gitosc\scala-sample\out\production\scala-sample\com\usoft>javap -p Student.class
Compiled from "Student.scala"
public class com.usoft.Student {
  private final java.lang.String name;
  private final int age;
  private int _id;
  private int _id();
  private void _id_$eq(int);
  public int id();
  public void id_$eq(int);
  public java.lang.String sayHi();
  public com.usoft.Student(java.lang.String, int);
}

_id 作为Stuent类的一个属性字段,显式的定义了reader method 和 writer method

object Main0 {
  def main(args: Array[String]) {
    println("hello world!!")

    val s = new Student("xxggy", 12)
    println(s.id)
    s.id = "xxggyy".hashCode
    println(s.id)
  }
}

通过reader method 和 writer method读写_id 的值。同时还要注意到因为该field是用private定义的,

scala 还隐式的生成了这两个方法,这两个方法都是private私有的。

private int _id();
private void _id_$eq(int);


private val 定义field

class Student0(name: String, age: Int) {

  private val _id: Int = name.hashCode

  def id: Int = _id

  def sayHi(): String = {
    "my name is " + name + ",my age is " + age
  }
}

在类中 使用 private val声明 _id ,由于val是不可变的,所以只能有reader method。

val s0 = new Student0("xx", 23)
println(s0.id)

反编译结果,

C:\WorkSpace5-gitosc\scala-sample\out\production\scala-sample\com\usoft>javap -p Student0.class
Compiled from "Student.scala"
public class com.usoft.Student0 {
  private final java.lang.String name;
  private final int age;
  private final int _id;
  private int _id();
  public int id();
  public java.lang.String sayHi();
  public com.usoft.Student0(java.lang.String, int);
}

val定义的不可变的变量是final类型的 private final int _id;。还可以看到scala隐式的生成的private int _id()方法,这个方法不是我们定义的。


val 和 var 定义field

class Student1(name: String, age: Int) {

  val _id: Int = name.hashCode

  def id: Int = _id

  def sayHi(): String = {
    "my name is " + name + ",my age is " + age
  }
}

class Student2(name: String, age: Int) {

  var _id: Int = name.hashCode

  def id: Int = _id //相当于getter方法

  def id_=(newId: Int): Unit = _id = newId //相当于setter方法

  def sayHi(): String = {
    "my name is " + name + ",my age is " + age
  }
}

上面两个类都是直接用var和val直接定义的,没有加访问修饰符,通过反编译我们来看一下不加访问修饰符有什么效果。

C:\WorkSpace5-gitosc\scala-sample\out\production\scala-sample\com\usoft>javap -p Student1.class
Compiled from "Student.scala"
public class com.usoft.Student1 {
  private final java.lang.String name;
  private final int age;
  private final int _id;
  public int _id();//scala隐式的生成的reader方法
  public int id();//定义的reader方法
  public java.lang.String sayHi();
  public com.usoft.Student1(java.lang.String, int);
}

C:\WorkSpace5-gitosc\scala-sample\out\production\scala-sample\com\usoft>javap -p Student2.class
Compiled from "Student.scala"
public class com.usoft.Student2 {
  private final java.lang.String name;
  private final int age;
  private int _id;
  public int _id();//scala隐式的生成的reader方法
  public void _id_$eq(int); // scala隐式的生成的
  public int id();//定义的reader方法
  public void id_$eq(int);//定义的writer方法
  public java.lang.String sayHi();
  public com.usoft.Student2(java.lang.String, int);
}

这样的话 效果就很明显了。


val 和 private val定义field

class Student3(name: String, age: Int) {

  val _id: Int = name.hashCode

  def sayHi(): String = {
    "my name is " + name + ",my age is " + age
  }
}


class Student4(name: String, age: Int) {

  private val _id: Int = name.hashCode

  def sayHi(): String = {
    "my name is " + name + ",my age is " + age
  }
}

反编译比较一下异同,

C:\WorkSpace5-gitosc\scala-sample\out\production\scala-sample\com\usoft>javap -p Student3.class
Compiled from "Student.scala"
public class com.usoft.Student3 {
  private final java.lang.String name;
  private final int age;
  private final int _id;
  public int _id();
  public java.lang.String sayHi();
  public com.usoft.Student3(java.lang.String, int);
}

C:\WorkSpace5-gitosc\scala-sample\out\production\scala-sample\com\usoft>javap -p Student4.class
Compiled from "Student.scala"
public class com.usoft.Student4 {
  private final java.lang.String name;
  private final int age;
  private final int _id;
  private int _id();
  public java.lang.String sayHi();
  public com.usoft.Student4(java.lang.String, int);
}

用val定义的 reader method 是:

  public int _id();

用private val定义的 reader method 是:

  private int _id();

差别就在这里。其实我认为 在field的定义上加的访问修饰符,只能加 private 和 protected 访问修饰符,表示该field的自动生成的reader method的访问修饰符是 private。

加 protected访问修饰符,生成的reader method还是public的,可以进行验证,

class Student5(name: String, age: Int) {
  protected val _id: Int = name.hashCode

  def sayHi(): String = {
    "my name is " + name + ",my age is " + age
  }
}

反编译,

C:\WorkSpace5-gitosc\scala-sample\out\production\scala-sample\com\usoft>javap -p Student5.class
Compiled from "Student.scala"
public class com.usoft.Student5 {
  private final java.lang.String name;
  private final int age;
  private final int _id;
  public int _id();
  public java.lang.String sayHi();
  public com.usoft.Student5(java.lang.String, int);
}

你看  public int _id();这个reader method还是public权限的。

=====================END=====================

你可能感兴趣的:(Scala Fields in Classes)