Scala学习笔记(1)-类-var-val

开始接触学习Scala,边学边记。


作为参考和对比,首先从JavaPOJO开始;

定义一个Person类(为防止和ScalaPerson类重名冲突,将该类放在gao.java目录下),如下:

package gao.java;
public class Person {
    private String name;
    private int age;
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
}

我们可以使用javap查看一下Person类编译后的Person.class文件:

$ javap -p target/scala-2.11/classes/gao/java/Person.class
Compiled from "Person.java"
public class gao.java.Person {
    private java.lang.String name;
    private int age;
    public gao.java.Person(java.lang.String, int);  // 构造方法
    public java.lang.String getName();  // getter方法
    public void setName(java.lang.String);  // setter方法
    public int getAge();  // getter方法
    public void setAge(int);  // setter方法
}


再来看看Scala如何定义Person类(在gao目录下):

package gao
class Person(var name:String, var age:Int)

哇塞!这就完了?相信大多数人第一次见到都会和我一样好奇。非常的简单!

我们也使用javap查看一下该Scala类编译后的Person.class文件:

$ javap -p target/scala-2.11/classes/gao/Person.class
Compiled from "Person.scala"
public class gao.Person {
  private java.lang.String name;
  private int age;
  public java.lang.String name();  // getter方法
  public void name_$eq(java.lang.String);  // setter方法
  public int age();  // getter方法
  public void age_$eq(int);  // setter方法
  public gao.Person(java.lang.String, int);  // 构造方法
}

1)在.class文件中,除了getter/setter方法的方法名看起来比较别扭之外,其他没有什么不同;

2)不过.class文件是给JVM看的,而对JVM来说,只要是有效的方法名,又有什么区别呢。

3)对于程序员来说,编码效率相对提高了很多(27=>2行)。

4)属性的访问修饰符自动编译为private

5getter/setter方法自动编译为public


Scala的方法调用也非常简单,为了简便,演示如下:

package gao
object Main {
  def main(args: Array[String]) {
    val person = new Person("Jack", 28)
    println(person.name)    // 调用getter方法,然后打印到标准输出
    println(person.age)       // 调用getter方法,然后打印到标准输出
    person.name = "Rose"  // 调用setter方法赋值
    person.age = 27            // 调用setter方法赋值
    println(person.name)   // 再调用getter方法,然后打印到标准输出
    println(person.age)      // 再调用getter方法,然后打印到标准输出
  }
}

输出如下:

Jack
28
Rose
27


再使用javap查看一下这个Main.class文件,发现它只有一个Javamain方法:

$ javap -p target/scala-2.11/classes/gao/Main.class
Compiled from "Main.scala"
public final class gao.Main {
  public static void main(java.lang.String[]);
}

Scala中,分别使用valvar来声明值和变量。

所谓值就是常量,不可变量。还是使用代码来演示比较清晰,修改ScalaPerson类如下:

package gao
class Person(val name:String, var age:Int)
其实这还看不出什么差别,不过通过方法调用就很容易看出不同,如图所示,不能给val修饰的属性赋值;



为什么呢?

这还是要使用javap来的比较清楚:

$ javap -p target/scala-2.11/classes/gao/Person.class
Compiled from "Person.scala"
public class gao.Person {
  private final java.lang.String name;
  private int age;
  public java.lang.String name();
  public int age();
  public void age_$eq(int);
  public gao.Person(java.lang.String, int);
}

原来val修饰的字段被编译成final的,而且不会有setter方法,所以不能赋值。

Scala建议在赋值时,优先选择使用val,在必须使用var的情况下再使用var


从上边示例看出,Scala编译器自动将类字段的访问修饰符编译为private

那如果我们在代码中,显式的类字段标识为private会怎样呢?

package gao
class Person(val name:String, var age:Int) {
  private val legs = 4
  var brother = 2
}

使用javap查看编译后的.class文件内容:

$ javap -p target/scala-2.11/classes/gao/Person.class
Compiled from "Person.scala"
public class gao.Person {
    private final java.lang.String name;
    private int age;
    private final int legs;
    private int brother;
    public java.lang.String name();
    public int age();
    public void age_$eq(int);
    private int legs();  // getter方法私有,外部不能访问,只能在内部使用,还弄个getter方法干什么用?
    public int brother();  // getter方法
    public void brother_$eq(int);  // setter方法
    public gao.Person(java.lang.String, int);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Go in memory

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值