Last active
February 18, 2022 13:49
-
-
Save cb372/dc0753567ae53f49d78d2e34fe25ea75 to your computer and use it in GitHub Desktop.
Explaining default args using javap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.time.Instant | |
object Foo { | |
case class Timers( | |
timer1: Long, | |
timer2: Long = Instant.now().toEpochMilli, | |
timer3: Long | |
) | |
val a = Timers( | |
timer1 = Instant.now().toEpochMilli, | |
timer3 = Instant.now().toEpochMilli | |
) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ javap -c 'Foo$.class' | |
Compiled from "Foo.scala" | |
public final class Foo$ { | |
public static final Foo$ MODULE$; | |
public static {}; | |
Code: | |
0: new #2 // class Foo$ | |
3: dup | |
4: invokespecial #22 // Method "<init>":()V | |
7: putstatic #24 // Field MODULE$:LFoo$; | |
10: invokestatic #30 // Method java/time/Instant.now:()Ljava/time/Instant; | |
13: invokevirtual #34 // Method java/time/Instant.toEpochMilli:()J | |
16: lstore_0 | |
17: invokestatic #30 // Method java/time/Instant.now:()Ljava/time/Instant; | |
20: invokevirtual #34 // Method java/time/Instant.toEpochMilli:()J | |
23: lstore_2 | |
24: getstatic #37 // Field Foo$Timers$.MODULE$:LFoo$Timers$; | |
27: invokevirtual #40 // Method Foo$Timers$.apply$default$2:()J | |
30: lstore 4 | |
32: new #7 // class Foo$Timers | |
35: dup | |
36: lload_0 | |
37: lload 4 | |
39: lload_2 | |
40: invokespecial #43 // Method Foo$Timers."<init>":(JJJ)V | |
43: putstatic #45 // Field a:LFoo$Timers; | |
46: return | |
public Foo$Timers a(); | |
Code: | |
0: getstatic #45 // Field a:LFoo$Timers; | |
3: areturn | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ javap -c 'Foo$Timers$.class' | |
Compiled from "Foo.scala" | |
public class Foo$Timers$ extends scala.runtime.AbstractFunction3<java.lang.Object, java.lang.Object, java.lang.Object, Foo$Timers> implements java.io.Serializable { | |
public static final Foo$Timers$ MODULE$; | |
... | |
public long apply$default$2(); | |
Code: | |
0: invokestatic #31 // Method java/time/Instant.now:()Ljava/time/Instant; | |
3: invokevirtual #34 // Method java/time/Instant.toEpochMilli:()J | |
6: lreturn | |
... | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
val a
is initialized when theFoo$
class is loaded, in thepublic static {}
method. This method does the following:invokestatic
+invokevirtual
) callInstant.now().toEpochMilli
lstore_0
) save the resultinglong
to local variable 0 (it will use it later as the first argument to theTimers
constructor)invokestatic
+invokevirtual
) callInstant.now().toEpochMilli
againlstore_2
) save the result to local variable 2 (it will use it later as the third argument to the constructor)getstatic
+invokevirtual
) callFoo$Timers$.apply$default$2
(which in turn callsInstant.now().toEpochMilli
and returns the result)lstore 4
) save the result to local variable 4 (it will use it later as the second argument to the constructor)new
+dup
) create a new (uninitialized)Timers
instancelload_0
) push local variable 0 onto the stack for use as the first argument to theTimers
constructorlload 4
) push local variable 4 onto the stack for use as the second argumentlload_2
) push local variable 2 onto the stack for use as the third argumentinvokespecial
) call theTimers
constructor, which pops the 3 args off the stackputstatic
) save theTimers
instance to the fielda
So in summary,
Instant.now.toEpochMilli
is called 3 times, once for each constructor arg, so the values could all be different.