Scala Fields in Classes

Scala Fields in Classesjava

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。反編譯以下,git

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 methodspa

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

scala 還隱式的生成了這兩個方法,這兩個方法都是private私有的。code

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。get

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

反編譯結果,hash

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()方法,這個方法不是咱們定義的。it


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直接定義的,沒有加訪問修飾符,經過反編譯咱們來看一下不加訪問修飾符有什麼效果。io

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=====================

相關文章
相關標籤/搜索