前言
本文记录了初学Scala代码笔记以及反编译的java代码以供加深对scala代码运行过程的理解。
函数声明
scala源码
object ScalaFunction1 {
def main(args:Array[String]):Unit={
//类似java规范的调用形式
println(testSum1(10, 20)) //返回30
println(testSum2(10,20)) //返回30
println(testSum3(10,20)) //返回()
//与java不同的调用形式
printScala1 //不带括号声明的只能不带括号调用
printScala2 //带括号声明的函数可以省略括号调用
printScala3()
}
//类似java规范的定义
def testSum1(v1:Int,v2:Int):Int={ //返回值为Unit不报错,但是返回空对象(),java中不允许而scala允许
return v1+v2
}
def testSum2(v1:Int,v2:Int):Int={
v1 + v2 //return可以省略,默认返回最后一句的结果
}
def testSum3(v1:Int,v2:Int):Unit={ //此处不可改为int,因为println返回为空
println(v1+v2)
}
//与java规范不同的函数声明
def printScala1: Unit={//无参数可以省略括号,但是调用不可多加括号
println("Scala")
}
def printScala2()={ //返回结果类型可以省略
println("Scala")
}
def printScala3(){ //返回结果为空时还可以省略=
println("Scala")
}
}
反编译后的java代码
object编译后的字节码文件有两个,一个只是起到壳的作用,另一个是真正的执行过程。
可以看到下面这个代码中均是在调用,很显然这个代码就是所谓的壳了。
import scala.reflect.ScalaSignature;
@ScalaSignature(bytes="\006\001\005;Q!\001\002\t\002\025\tabU2bY\0064UO\\2uS>t\027GC\001\004\003%\031\007.\0319uKJ\004\024g\001\001\021\005\0319Q\"\001\002\007\013!\021\001\022A\005\003\035M\033\027\r\\1Gk:\034G/[8ocM\021qA\003\t\003\0279i\021\001\004\006\002\033\005)1oY1mC&\021q\002\004\002\007\003:L(+\0324\t\013E9A\021\001\n\002\rqJg.\033;?)\005)\001\"\002\013\b\t\003)\022\001B7bS:$\"AF\r\021\005-9\022B\001\r\r\005\021)f.\033;\t\013i\031\002\031A\016\002\t\005\024xm\035\t\004\027qq\022BA\017\r\005\025\t%O]1z!\ty\"E\004\002\fA%\021\021\005D\001\007!J,G-\0324\n\005\r\"#AB*ue&twM\003\002\"\031!)ae\002C\001O\005AA/Z:u'Vl\027\007F\002)W5\002\"aC\025\n\005)b!aA%oi\")A&\na\001Q\005\021a/\r\005\006]\025\002\r\001K\001\003mJBQ\001M\004\005\002E\n\001\002^3tiN+XN\r\013\004QI\032\004\"\002\0270\001\004A\003\"\002\0300\001\004A\003\"B\033\b\t\0031\024\001\003;fgR\034V/\\\032\025\007Y9\004\bC\003-i\001\007\001\006C\003/i\001\007\001\006C\003;\017\021\0051(A\006qe&tGoU2bY\006\fT#\001\f\t\013u:A\021\001 \002\027A\024\030N\034;TG\006d\027M\r\013\002-!)\001i\002C\001}\005Y\001O]5oiN\033\027\r\\14\001")
public final class ScalaFunction1
{
public static void printScala3()
{
ScalaFunction1..MODULE$.printScala3();
}
public static void printScala2()
{
ScalaFunction1..MODULE$.printScala2();
}
public static void printScala1()
{
ScalaFunction1..MODULE$.printScala1();
}
public static void testSum3(int paramInt1, int paramInt2)
{
ScalaFunction1..MODULE$.testSum3(paramInt1, paramInt2);
}
public static int testSum2(int paramInt1, int paramInt2)
{
return ScalaFunction1..MODULE$.testSum2(paramInt1, paramInt2);
}
public static int testSum1(int paramInt1, int paramInt2)
{
return ScalaFunction1..MODULE$.testSum1(paramInt1, paramInt2);
}
public static void main(String[] paramArrayOfString)
{
ScalaFunction1..MODULE$.main(paramArrayOfString);
}
}
真正的执行过程在一个叫做ScalaFunction1$的字节码文件中
import scala.Predef.;
import scala.runtime.BoxedUnit;
import scala.runtime.BoxesRunTime;
public final class ScalaFunction1$
{
public static final MODULE$;
static
{
new ();
}
public void main(String[] args)
{
Predef..MODULE$.println(BoxesRunTime.boxToInteger(testSum1(10, 20)));
Predef..MODULE$.println(BoxesRunTime.boxToInteger(testSum2(10, 20)));
testSum3(10, 20);Predef..MODULE$.println(BoxedUnit.UNIT);
printScala1();
printScala2();
printScala3();
}
public int testSum1(int v1, int v2)
{
return v1 + v2;
}
public int testSum2(int v1, int v2)
{
return v1 + v2;
}
public void testSum3(int v1, int v2)
{
Predef..MODULE$.println(BoxesRunTime.boxToInteger(v1 + v2));
}
public void printScala1()
{
Predef..MODULE$.println("Scala");
}
public void printScala2()
{
Predef..MODULE$.println("Scala");
}
public void printScala3()
{
Predef..MODULE$.println("Scala");
}
private ScalaFunction1$()
{
MODULE$ = this;
}
}
变量声明
object ScalaVar {
val age =10 //值不可再改变,编译后是final修饰
def main(args:Array[String]):Unit={
val v1 = 20 //值不可再改变,但编译后并不是final修饰
var v2 = 30 //值可以被修改
}
}
scala源码
object ScalaVar {
val age =10 //值不可再改变,编译后是final修饰
def main(args:Array[String]):Unit={
val v1 = 20 //值不可再改变,但编译后并不是final修饰
var v2 = 30 //值可以被修改
}
}
反编译后的ava代码
下面还是壳
import scala.reflect.ScalaSignature;
@ScalaSignature(bytes="\006\0015:Q!\001\002\t\002\025\t\001bU2bY\0064\026M\035\006\002\007\005I1\r[1qi\026\024\b'M\002\001!\t1q!D\001\003\r\025A!\001#\001\n\005!\0316-\0317b-\006\0248CA\004\013!\tYa\"D\001\r\025\005i\021!B:dC2\f\027BA\b\r\005\031\te.\037*fM\")\021c\002C\001%\0051A(\0338jiz\"\022!\002\005\b)\035\021\r\021\"\001\026\003\r\tw-Z\013\002-A\0211bF\005\00311\0211!\0238u\021\031Qr\001)A\005-\005!\021mZ3!\021\025ar\001\"\001\036\003\021i\027-\0338\025\005y\t\003CA\006 \023\t\001CB\001\003V]&$\b\"\002\022\034\001\004\031\023\001B1sON\0042a\003\023'\023\t)CBA\003BeJ\f\027\020\005\002(U9\0211\002K\005\003S1\ta\001\025:fI\0264\027BA\026-\005\031\031FO]5oO*\021\021\006\004")
public final class ScalaVar
{
public static void main(String[] paramArrayOfString)
{
ScalaVar..MODULE$.main(paramArrayOfString);
}
public static int age()
{
return ScalaVar..MODULE$.age();
}
}
真正的执行过程
public final class ScalaVar$
{
public static final MODULE$;
private final int age;
static
{
new ();
}
public int age()
{
return this.age;
}
public void main(String[] args)
{
int v1 = 20;
int v2 = 30;
}
private ScalaVar$()
{
MODULE$ = this;this.age = 10;
}
}
函数引用
scala源码
object ScalaFunction2 {
def main(args:Array[String]):Unit={
var M = testM2 _ //引用函数
println(M) //<function0> 0表示无参
println(M()) //<function0> 0表示无参
println(M()()) //()
}
def testM1(): Unit ={
println("Test M1...")
}
def testM2()={ //此处返回结果不可以是Unit
testM1 _
}
}
反编译后的ava代码
依旧是壳
import scala.Function0;
import scala.reflect.ScalaSignature;
import scala.runtime.BoxedUnit;
@ScalaSignature(bytes="\006\0019:Q!\001\002\t\002\025\tabU2bY\0064UO\\2uS>t'GC\001\004\003%\031\007.\0319uKJ\004\024g\001\001\021\005\0319Q\"\001\002\007\013!\021\001\022A\005\003\035M\033\027\r\\1Gk:\034G/[8oeM\021qA\003\t\003\0279i\021\001\004\006\002\033\005)1oY1mC&\021q\002\004\002\007\003:L(+\0324\t\013E9A\021\001\n\002\rqJg.\033;?)\005)\001\"\002\013\b\t\003)\022\001B7bS:$\"AF\r\021\005-9\022B\001\r\r\005\021)f.\033;\t\013i\031\002\031A\016\002\t\005\024xm\035\t\004\027qq\022BA\017\r\005\025\t%O]1z!\ty\"E\004\002\fA%\021\021\005D\001\007!J,G-\0324\n\005\r\"#AB*ue&twM\003\002\"\031!)ae\002C\001O\0051A/Z:u\033F\"\022A\006\005\006S\035!\tAK\001\007i\026\034H/\024\032\025\003-\0022a\003\027\027\023\tiCBA\005Gk:\034G/[8oa\001")
public final class ScalaFunction2
{
public static Function0<BoxedUnit> testM2()
{
return ScalaFunction2..MODULE$.testM2(); //这里的ScalaFunction2.实际上是ScalaFunction2$,反编译失败的字符
}
public static void testM1()
{
ScalaFunction2..MODULE$.testM1();
}
public static void main(String[] paramArrayOfString)
{
ScalaFunction2..MODULE$.main(paramArrayOfString);
}
}
真正的执行过程
···
import scala.Function0;
import scala.Predef.;
import scala.Serializable;
import scala.runtime.AbstractFunction0;
import scala.runtime.AbstractFunction0.mcV.sp;
import scala.runtime.BoxedUnit;
public final class ScalaFunction2$
{
public static final MODULE$;
static
{
new ();
}
public void main(String[] args)
{
Function0 M = new AbstractFunction0()
{
public static final long serialVersionUID = 0L;
public final Function0<BoxedUnit> apply()
{
return ScalaFunction2..MODULE$.testM2();
}
};
Predef..MODULE$.println(M);
Predef..MODULE$.println(M.apply());
((Function0)M.apply()).apply$mcV$sp();Predef..MODULE$.println(BoxedUnit.UNIT);
}
public void testM1()
{
Predef..MODULE$.println("Test M1...");
}
public Function0<BoxedUnit> testM2()
{
new AbstractFunction0.mcV.sp()
{
public static final long serialVersionUID = 0L;
public void apply$mcV$sp()
{
ScalaFunction2..MODULE$.testM1();
}
public final void apply()
{
apply$mcV$sp();
}
};
}
private ScalaFunction2$()
{
MODULE$ = this;
}
}
···