jerry
May 16, 2018, 9:30am
1
after i scalac the follow code, i get servel class file.
the test code:
// HightOrder.scala
object SalaryRaiser {
private def promotion(salaries: List[Double], promotionFunction: Double => Double): List[Double] =
salaries.map(promotionFunction)
def smallPromotion(salaries: List[Double]): List[Double] =
promotion(salaries, salary => salary * 1.1)
def bigPromotion(salaries: List[Double]): List[Double] =
promotion(salaries, salary => salary * math.log(salary))
def hugePromotion(salaries: List[Double]): List[Double] =
promotion(salaries, salary => salary * salary)
def factorial(x: Int): Int = {
/* here is the nested method */
def fact(x: Int, accumulator: Int): Int = {
if (x <= 1) accumulator
else fact(x - 1, x * accumulator)
}
fact(x, 1)
}
}
object SalaryRaiserTest extends App {
val salaries = Seq(20000, 70000, 40000)
val doubleSalary = (x: Int) => x * 2
val newSalaries = salaries.map(doubleSalary)
println(newSalaries)
println("Factorial of 2: " + SalaryRaiser.factorial(2))
println("Factorial of 3: " + SalaryRaiser.factorial(3))
}
class file:
see@17:28:30 scala-tour ll *.class
-rw-rw-r--. 1 see see 1.3K May 16 17:23 SalaryRaiser.class
-rw-rw-r--. 1 see see 3.4K May 16 17:23 SalaryRaiser$.class
-rw-rw-r--. 1 see see 1.5K May 16 17:23 SalaryRaiserTest.class
-rw-rw-r--. 1 see see 5.0K May 16 17:23 SalaryRaiserTest$.class
-rw-rw-r--. 1 see see 833 May 16 17:23 SalaryRaiserTest$delayedInit$body.class
the i use:
javap -v SalaryRaiser.class > SalaryRaiser.p
javap -v SalaryRaiser\$.class > SalaryRaiser\$.p
i can only find the nested method in constant pool, but where is the method bytecode?
my enviroment is:
scala-2.12.6-1.noarch
openjdk version "1.8.0_161"
OpenJDK Runtime Environment (build 1.8.0_161-b14)
OpenJDK 64-Bit Server VM (build 25.161-b14, mixed mode)
jerry
May 16, 2018, 9:36am
2
the full output of SalaryRaiser$.p
Classfile /home/see/work/container/play/scala-tour/SalaryRaiser$.class
Last modified May 16, 2018; size 3381 bytes
MD5 checksum a2cada09454f343e93b379b70d39c273
Compiled from "HightOrder.scala"
public final class SalaryRaiser$
BootstrapMethods:
0: #48 invokestatic java/lang/invoke/LambdaMetafactory.altMetafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
Method arguments:
#50 (D)D
#54 invokestatic SalaryRaiser$.$anonfun$smallPromotion$1:(D)D
#50 (D)D
#55 3
#56 1
#58 scala/Serializable
1: #48 invokestatic java/lang/invoke/LambdaMetafactory.altMetafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
Method arguments:
#50 (D)D
#69 invokestatic SalaryRaiser$.$anonfun$bigPromotion$1:(D)D
#50 (D)D
#55 3
#56 1
#58 scala/Serializable
2: #48 invokestatic java/lang/invoke/LambdaMetafactory.altMetafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
Method arguments:
#50 (D)D
#75 invokestatic SalaryRaiser$.$anonfun$hugePromotion$1:(D)D
#50 (D)D
#55 3
#56 1
#58 scala/Serializable
3: #109 invokestatic scala/runtime/LambdaDeserialize.bootstrap:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/invoke/MethodHandle;)Ljava/lang/invoke/CallSite;
Method arguments:
#54 invokestatic SalaryRaiser$.$anonfun$smallPromotion$1:(D)D
#69 invokestatic SalaryRaiser$.$anonfun$bigPromotion$1:(D)D
#75 invokestatic SalaryRaiser$.$anonfun$hugePromotion$1:(D)D
SourceFile: "HightOrder.scala"
InnerClasses:
public static final #10= #7 of #9; //Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles
ScalaInlineInfo: length = 0x36
01 01 00 0A 00 42 00 31 01 00 48 00 31 01 00 33
00 31 01 00 0F 00 0E 01 00 41 00 29 01 00 50 00
51 01 00 4D 00 4E 01 00 47 00 29 01 00 12 00 13
01 00 28 00 29 01
Scala: length = 0x0
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_FINAL, ACC_SUPER
Constant pool:
#1 = Utf8 SalaryRaiser$
#2 = Class #1 // SalaryRaiser$
#3 = Utf8 java/lang/Object
#4 = Class #3 // java/lang/Object
#5 = Utf8 HightOrder.scala
#6 = Utf8 java/lang/invoke/MethodHandles$Lookup
#7 = Class #6 // java/lang/invoke/MethodHandles$Lookup
#8 = Utf8 java/lang/invoke/MethodHandles
#9 = Class #8 // java/lang/invoke/MethodHandles
#10 = Utf8 Lookup
#11 = Utf8 MODULE$
#12 = Utf8 LSalaryRaiser$;
#13 = Utf8 <clinit>
#14 = Utf8 ()V
#15 = Utf8 <init>
#16 = NameAndType #15:#14 // "<init>":()V
#17 = Methodref #2.#16 // SalaryRaiser$."<init>":()V
#18 = Utf8 promotion
#19 = Utf8 (Lscala/collection/immutable/List;Lscala/Function1;)Lscala/collection/immutable/List;
#20 = Utf8 salaries
#21 = Utf8 promotionFunction
#22 = Utf8 scala/collection/immutable/List$
#23 = Class #22 // scala/collection/immutable/List$
#24 = Utf8 Lscala/collection/immutable/List$;
#25 = NameAndType #11:#24 // MODULE$:Lscala/collection/immutable/List$;
#26 = Fieldref #23.#25 // scala/collection/immutable/List$.MODULE$:Lscala/collection/immutable/List$;
#27 = Utf8 canBuildFrom
#28 = Utf8 ()Lscala/collection/generic/CanBuildFrom;
#29 = NameAndType #27:#28 // canBuildFrom:()Lscala/collection/generic/CanBuildFrom;
#30 = Methodref #23.#29 // scala/collection/immutable/List$.canBuildFrom:()Lscala/collection/generic/CanBuildFrom;
#31 = Utf8 scala/collection/immutable/List
#32 = Class #31 // scala/collection/immutable/List
#33 = Utf8 map
#34 = Utf8 (Lscala/Function1;Lscala/collection/generic/CanBuildFrom;)Ljava/lang/Object;
#35 = NameAndType #33:#34 // map:(Lscala/Function1;Lscala/collection/generic/CanBuildFrom;)Ljava/lang/Object;
#36 = Methodref #32.#35 // scala/collection/immutable/List.map:(Lscala/Function1;Lscala/collection/generic/CanBuildFrom;)Ljava/lang/Object;
#37 = Utf8 this
#38 = Utf8 Lscala/collection/immutable/List;
#39 = Utf8 Lscala/Function1;
#40 = Utf8 smallPromotion
#41 = Utf8 (Lscala/collection/immutable/List;)Lscala/collection/immutable/List;
#42 = Utf8 java/lang/invoke/LambdaMetafactory
#43 = Class #42 // java/lang/invoke/LambdaMetafactory
#44 = Utf8 altMetafactory
#45 = Utf8 (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
#46 = NameAndType #44:#45 // altMetafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
#47 = Methodref #43.#46 // java/lang/invoke/LambdaMetafactory.altMetafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
#48 = MethodHandle #6:#47 // invokestatic java/lang/invoke/LambdaMetafactory.altMetafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
#49 = Utf8 (D)D
#50 = MethodType #49 // (D)D
#51 = Utf8 $anonfun$smallPromotion$1
#52 = NameAndType #51:#49 // $anonfun$smallPromotion$1:(D)D
#53 = Methodref #2.#52 // SalaryRaiser$.$anonfun$smallPromotion$1:(D)D
#54 = MethodHandle #6:#53 // invokestatic SalaryRaiser$.$anonfun$smallPromotion$1:(D)D
#55 = Integer 3
#56 = Integer 1
#57 = Utf8 scala/Serializable
#58 = Class #57 // scala/Serializable
#59 = Utf8 apply$mcDD$sp
#60 = Utf8 ()Lscala/runtime/java8/JFunction1$mcDD$sp;
#61 = NameAndType #59:#60 // apply$mcDD$sp:()Lscala/runtime/java8/JFunction1$mcDD$sp;
#62 = InvokeDynamic #0:#61 // #0:apply$mcDD$sp:()Lscala/runtime/java8/JFunction1$mcDD$sp;
#63 = NameAndType #18:#19 // promotion:(Lscala/collection/immutable/List;Lscala/Function1;)Lscala/collection/immutable/List;
#64 = Methodref #2.#63 // SalaryRaiser$.promotion:(Lscala/collection/immutable/List;Lscala/Function1;)Lscala/collection/immutable/List;
#65 = Utf8 bigPromotion
#66 = Utf8 $anonfun$bigPromotion$1
#67 = NameAndType #66:#49 // $anonfun$bigPromotion$1:(D)D
#68 = Methodref #2.#67 // SalaryRaiser$.$anonfun$bigPromotion$1:(D)D
#69 = MethodHandle #6:#68 // invokestatic SalaryRaiser$.$anonfun$bigPromotion$1:(D)D
#70 = InvokeDynamic #1:#61 // #1:apply$mcDD$sp:()Lscala/runtime/java8/JFunction1$mcDD$sp;
#71 = Utf8 hugePromotion
#72 = Utf8 $anonfun$hugePromotion$1
#73 = NameAndType #72:#49 // $anonfun$hugePromotion$1:(D)D
#74 = Methodref #2.#73 // SalaryRaiser$.$anonfun$hugePromotion$1:(D)D
#75 = MethodHandle #6:#74 // invokestatic SalaryRaiser$.$anonfun$hugePromotion$1:(D)D
#76 = InvokeDynamic #2:#61 // #2:apply$mcDD$sp:()Lscala/runtime/java8/JFunction1$mcDD$sp;
#77 = Utf8 factorial
#78 = Utf8 (I)I
#79 = Utf8 x
#80 = Utf8 fact$1
#81 = Utf8 (II)I
#82 = NameAndType #80:#81 // fact$1:(II)I
#83 = Methodref #2.#82 // SalaryRaiser$.fact$1:(II)I
#84 = Utf8 I
#85 = Utf8 salary
#86 = Double 1.1d
#88 = Utf8 D
#89 = Utf8 scala/math/package$
#90 = Class #89 // scala/math/package$
#91 = Utf8 Lscala/math/package$;
#92 = NameAndType #11:#91 // MODULE$:Lscala/math/package$;
#93 = Fieldref #90.#92 // scala/math/package$.MODULE$:Lscala/math/package$;
#94 = Utf8 log
#95 = NameAndType #94:#49 // log:(D)D
#96 = Methodref #90.#95 // scala/math/package$.log:(D)D
#97 = Utf8 accumulator
#98 = Methodref #4.#16 // java/lang/Object."<init>":()V
#99 = NameAndType #11:#12 // MODULE$:LSalaryRaiser$;
#100 = Fieldref #2.#99 // SalaryRaiser$.MODULE$:LSalaryRaiser$;
#101 = Utf8 $deserializeLambda$
#102 = Utf8 (Ljava/lang/invoke/SerializedLambda;)Ljava/lang/Object;
#103 = Utf8 scala/runtime/LambdaDeserialize
#104 = Class #103 // scala/runtime/LambdaDeserialize
#105 = Utf8 bootstrap
#106 = Utf8 (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/invoke/MethodHandle;)Ljava/lang/invoke/CallSite;
#107 = NameAndType #105:#106 // bootstrap:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/invoke/MethodHandle;)Ljava/lang/invoke/CallSite;
#108 = Methodref #104.#107 // scala/runtime/LambdaDeserialize.bootstrap:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/invoke/MethodHandle;)Ljava/lang/invoke/CallSite;
#109 = MethodHandle #6:#108 // invokestatic scala/runtime/LambdaDeserialize.bootstrap:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/invoke/MethodHandle;)Ljava/lang/invoke/CallSite;
#110 = Utf8 lambdaDeserialize
#111 = NameAndType #110:#102 // lambdaDeserialize:(Ljava/lang/invoke/SerializedLambda;)Ljava/lang/Object;
#112 = InvokeDynamic #3:#111 // #3:lambdaDeserialize:(Ljava/lang/invoke/SerializedLambda;)Ljava/lang/Object;
#113 = Utf8 Code
#114 = Utf8 LocalVariableTable
#115 = Utf8 LineNumberTable
#116 = Utf8 Signature
#117 = Utf8 (Lscala/collection/immutable/List<Ljava/lang/Object;>;Lscala/Function1<Ljava/lang/Object;Ljava/lang/Object;>;)Lscala/collection/immutable/List<Ljava/lang/Object;>;
#118 = Utf8 MethodParameters
#119 = Utf8 (Lscala/collection/immutable/List<Ljava/lang/Object;>;)Lscala/collection/immutable/List<Ljava/lang/Object;>;
#120 = Utf8 StackMapTable
#121 = Utf8 BootstrapMethods
#122 = Utf8 SourceFile
#123 = Utf8 InnerClasses
#124 = Utf8 ScalaInlineInfo
#125 = Utf8 Scala
{
public static SalaryRaiser$ MODULE$;
flags: ACC_PUBLIC, ACC_STATIC
public static {};
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=1, locals=0, args_size=0
0: new #2 // class SalaryRaiser$
3: invokespecial #17 // Method "<init>":()V
6: return
public scala.collection.immutable.List<java.lang.Object> smallPromotion(scala.collection.immutable.List<java.lang.Object>);
flags: ACC_PUBLIC
Code:
stack=3, locals=2, args_size=2
0: aload_0
1: aload_1
2: invokedynamic #62, 0 // InvokeDynamic #0:apply$mcDD$sp:()Lscala/runtime/java8/JFunction1$mcDD$sp;
7: invokespecial #64 // Method promotion:(Lscala/collection/immutable/List;Lscala/Function1;)Lscala/collection/immutable/List;
10: areturn
LocalVariableTable:
Start Length Slot Name Signature
0 11 0 this LSalaryRaiser$;
0 11 1 salaries Lscala/collection/immutable/List;
LineNumberTable:
line 8: 0
Signature: #119 // (Lscala/collection/immutable/List<Ljava/lang/Object;>;)Lscala/collection/immutable/List<Ljava/lang/Object;>;
MethodParameters: length = 0x5
01 00 14 00 10
public scala.collection.immutable.List<java.lang.Object> bigPromotion(scala.collection.immutable.List<java.lang.Object>);
flags: ACC_PUBLIC
Code:
stack=3, locals=2, args_size=2
0: aload_0
1: aload_1
2: invokedynamic #70, 0 // InvokeDynamic #1:apply$mcDD$sp:()Lscala/runtime/java8/JFunction1$mcDD$sp;
7: invokespecial #64 // Method promotion:(Lscala/collection/immutable/List;Lscala/Function1;)Lscala/collection/immutable/List;
10: areturn
LocalVariableTable:
Start Length Slot Name Signature
0 11 0 this LSalaryRaiser$;
0 11 1 salaries Lscala/collection/immutable/List;
LineNumberTable:
line 11: 0
Signature: #119 // (Lscala/collection/immutable/List<Ljava/lang/Object;>;)Lscala/collection/immutable/List<Ljava/lang/Object;>;
MethodParameters: length = 0x5
01 00 14 00 10
public scala.collection.immutable.List<java.lang.Object> hugePromotion(scala.collection.immutable.List<java.lang.Object>);
flags: ACC_PUBLIC
Code:
stack=3, locals=2, args_size=2
0: aload_0
1: aload_1
2: invokedynamic #76, 0 // InvokeDynamic #2:apply$mcDD$sp:()Lscala/runtime/java8/JFunction1$mcDD$sp;
7: invokespecial #64 // Method promotion:(Lscala/collection/immutable/List;Lscala/Function1;)Lscala/collection/immutable/List;
10: areturn
LocalVariableTable:
Start Length Slot Name Signature
0 11 0 this LSalaryRaiser$;
0 11 1 salaries Lscala/collection/immutable/List;
LineNumberTable:
line 14: 0
Signature: #119 // (Lscala/collection/immutable/List<Ljava/lang/Object;>;)Lscala/collection/immutable/List<Ljava/lang/Object;>;
MethodParameters: length = 0x5
01 00 14 00 10
public int factorial(int);
flags: ACC_PUBLIC
Code:
stack=3, locals=2, args_size=2
0: aload_0
1: iload_1
2: iconst_1
3: invokespecial #83 // Method fact$1:(II)I
6: ireturn
LocalVariableTable:
Start Length Slot Name Signature
0 7 0 this LSalaryRaiser$;
0 7 1 x I
LineNumberTable:
line 21: 0
MethodParameters: length = 0x5
01 00 4F 00 10
public static final double $anonfun$smallPromotion$1(double);
flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_SYNTHETIC
Code:
stack=4, locals=2, args_size=1
0: dload_0
1: ldc2_w #86 // double 1.1d
4: dmul
5: dreturn
LocalVariableTable:
Start Length Slot Name Signature
0 6 0 salary D
LineNumberTable:
line 8: 0
MethodParameters: length = 0x5
01 00 55 00 10
public static final double $anonfun$bigPromotion$1(double);
flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_SYNTHETIC
Code:
stack=5, locals=2, args_size=1
0: dload_0
1: getstatic #93 // Field scala/math/package$.MODULE$:Lscala/math/package$;
4: dload_0
5: invokevirtual #96 // Method scala/math/package$.log:(D)D
8: dmul
9: dreturn
LocalVariableTable:
Start Length Slot Name Signature
0 10 0 salary D
LineNumberTable:
line 11: 0
MethodParameters: length = 0x5
01 00 55 00 10
public static final double $anonfun$hugePromotion$1(double);
flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_SYNTHETIC
Code:
stack=4, locals=2, args_size=1
0: dload_0
1: dload_0
2: dmul
3: dreturn
LocalVariableTable:
Start Length Slot Name Signature
0 4 0 salary D
LineNumberTable:
line 14: 0
MethodParameters: length = 0x5
01 00 55 00 10
}
scala> :pa
// Entering paste mode (ctrl-D to finish)
object SalaryRaiser {
private def promotion(salaries: List[Double], promotionFunction: Double => Double): List[Double] =
salaries.map(promotionFunction)
def smallPromotion(salaries: List[Double]): List[Double] =
promotion(salaries, salary => salary * 1.1)
def bigPromotion(salaries: List[Double]): List[Double] =
promotion(salaries, salary => salary * math.log(salary))
def hugePromotion(salaries: List[Double]): List[Double] =
promotion(salaries, salary => salary * salary)
def factorial(x: Int): Int = {
/* here is the nested method */
def fact(x: Int, accumulator: Int): Int = {
if (x <= 1) accumulator
else fact(x - 1, x * accumulator)
}
fact(x, 1)
}
}
// Exiting paste mode, now interpreting.
defined object SalaryRaiser
then
scala> :javap -pv SalaryRaiser#fact$1
private final int fact$1(int, int);
descriptor: (II)I
flags: ACC_PRIVATE, ACC_FINAL
Code:
stack=3, locals=3, args_size=3
0: iload_1
1: iconst_1
2: if_icmpgt 9
5: iload_2
6: goto 20
9: iload_1
10: iconst_1
11: isub
12: iload_1
13: iload_2
14: imul
15: istore_2
16: istore_1
17: goto 0
20: ireturn
LocalVariableTable:
Start Length Slot Name Signature
0 21 0 this L$line4/$read$$iw$$iw$SalaryRaiser$;
0 21 1 x I
0 21 2 accumulator I
LineNumberTable:
line 28: 0
line 29: 9
StackMapTable: number_of_entries = 3
frame_type = 0 /* same */
frame_type = 8 /* same */
frame_type = 74 /* same_locals_1_stack_item */
stack = [ int ]
MethodParameters:
Name Flags
x final
accumulator final
scala> :javap -help
usage :javap [opts] [path or class or -]...
-help Prints this help message
-verbose/-v Stack size, number of locals, method args
-private/-p Private classes and members
-package Package-private classes and members
-protected Protected classes and members
-public Public classes and members
-l Line and local variable tables
-c Disassembled code
-s Internal type signatures
-sysinfo System info of class
-constants Static final constants
-filter Filter REPL machinery from output
scala>
1 Like