首页 > 技术文章 > Scala 代码底层 demo 理解

sowhat1412 2019-10-25 09:48 原文

scala或者Java代码最终都会编译成JVM可识别的*.class 格式的二进制字节码,*.class 文件可用 jd-gui 软件打开。

举例一

aiguigu.scala 文件 用 scalac aiguigu.scala 该文件后 由于目标是object,scalac编译器会自动创造两个文件( aiguigu.class、 aiguigu$.class  )

object aiguigu{
  def main(args: Array[String]): Unit = {
    println("123")
  }
}
//aiguigu.scala
import scala.reflect.ScalaSignature;

@ScalaSignature(bytes="\006\001\025:Q!\001\002\t\002\025\tq!Y5hk&<WOC\001\004\003\035aT-\0349usz\032\001\001\005\002\007\0175\t!AB\003\t\005!\005\021BA\004bS\036,\030nZ;\024\005\035Q\001CA\006\017\033\005a!\"A\007\002\013M\034\027\r\\1\n\005=a!AB!osJ+g\rC\003\022\017\021\005!#\001\004=S:LGO\020\013\002\013!)Ac\002C\001+\005!Q.Y5o)\t1\022\004\005\002\f/%\021\001\004\004\002\005+:LG\017C\003\033'\001\0071$\001\003be\036\034\bcA\006\035=%\021Q\004\004\002\006\003J\024\030-\037\t\003?\tr!a\003\021\n\005\005b\021A\002)sK\022,g-\003\002$I\t11\013\036:j]\036T!!\t\007")
public final class aiguigu
{
  public static void main(String[] paramArrayOfString)
  {
    aiguigu$.MODULE$.main(paramArrayOfString);
  }
}
//aiguigu.class 反编译结果如上
import scala.Predef.;

public final class aiguigu$
{
  public static final  MODULE$;
  
  static
  {
    new ();
  }
  
  public void main(String[] args)
  {
    Predef$.MODULE$.println("123");
  }
  
  private aiguigu$()
  {
    MODULE$ = this;
  }
}
//  aiguigu$.class 文件反编译结果如上

通过上面编译发现, 当我们单独定义一个 object  类型的时候,scalac 编译器会自动构建类,然后接下来的思路也是 跟Java那套类似。

举例二

比如我们定义个如下的scala文件,scala  中的属性A定义其实还是private的在底层,只不过是在我们创建的时候系统自动搞了一个A(), A_$eq() 举例如下


object CatDemo{
  def main(args: Array[String]): Unit = {
    val cat = new Cat  //  创建一只猫
    cat.name = "小白" //  其实不是直接访问的属性,而是 cat.name_$eq("小白")
    println(cat.name) // 等价于cat.name()
    cat age = 10
    cat.color = "白色"
    printf("小猫信息如下:%s %d %s",cat.name,cat.age,cat.color)
  }
}
// 定义一个类Cat,一个class Cat 对应的字节码文件只有一个Cat.class 默认是public
class Cat {
  // 当我们生命 var name:String 时 底层对应的 private name  同事自动生成两个public方法, name() 类似 getter , name_$eq() 类似setter
  var name:String = ""
  var age:Int = _ // _ 会自动赋值给该变量的默认值
  var color:String = ""
}

上面文件编程后 会生成 Cat.class、CatDemo.class、 CatDemo$.class 两个文件,细节如下

 

举例三

scala代码,跟仿scala的Java代码如下。 

object Hello2{
  def main(args: Array[String]): Unit = {
    println("hello,scala")
  }
}
//aiguigu.scala

scala 一个文件可以定义若干类,每个类都会编译成一个.class 文件,只是为了了解底层而已,知其所以然

推荐阅读