Scala Fields in Classes
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);
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()方法,这个方法不是我们定义的。
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); }
这样的话 效果就很明显了。
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=====================