Hi guys, I want to know what exactly internal impl...
# compiler
c
Hi guys, I want to know what exactly internal implement of SAM by check it decompiler but I don't know the meaning of this statement, could you please give me some idea about this. Thanks.
Copy code
static {
   samTwo = (SamTwoArg)null.INSTANCE;
}
Here is my original code (from Atomic Kotlin book)
Copy code
package interfaces
import atomictest.eq

fun interface SamTwoArg {
  fun h(i: Int, j: Int): Int
}

val samTwo =  SamTwoArg { i, j -> i + j }

fun main() {
  samTwo.h(11, 47) eq 58
}
Here is decompiler result:
Copy code
// SamTwoArg.java
package interfaces;

import kotlin.Metadata;

@Metadata(
   mv = {1, 5, 1},
   k = 1,
   d1 = {"\u0000\u0012\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0000\n\u0002\u0010\b\n\u0002\b\u0003\bæ\u0080\u0001\u0018\u00002\u00020\u0001J\u0018\u0010\u0002\u001a\u00020\u00032\u0006\u0010\u0004\u001a\u00020\u00032\u0006\u0010\u0005\u001a\u00020\u0003H&¨\u0006\u0006"},
   d2 = {"Linterfaces/SamTwoArg;", "", "h", "", "i", "j", "AtomicKotlinCourse.main"}
)
public interface SamTwoArg {
   int h(int var1, int var2);
}
// SAMImplementationKt.java
package interfaces;

import atomictest.AtomicTestKt;
import kotlin.Metadata;
import org.jetbrains.annotations.NotNull;

@Metadata(
   mv = {1, 5, 1},
   k = 2,
   d1 = {"\u0000\u0010\n\u0000\n\u0002\u0018\u0002\n\u0002\b\u0003\n\u0002\u0010\u0002\n\u0000\u001a\u0006\u0010\u0004\u001a\u00020\u0005\"\u0011\u0010\u0000\u001a\u00020\u0001¢\u0006\b\n\u0000\u001a\u0004\b\u0002\u0010\u0003¨\u0006\u0006"},
   d2 = {"samTwo", "Linterfaces/SamTwoArg;", "getSamTwo", "()Linterfaces/SamTwoArg;", "main", "", "AtomicKotlinCourse.main"}
)
public final class SAMImplementationKt {
   @NotNull
   private static final SamTwoArg samTwo;

   @NotNull
   public static final SamTwoArg getSamTwo() {
      return samTwo;
   }

   public static final void main() {
      AtomicTestKt.eq(samTwo.h(11, 47), 58);
   }

   // $FF: synthetic method
   public static void main(String[] var0) {
      main();
   }

   static {
      samTwo = (SamTwoArg)null.INSTANCE;
   }
}
s
The decompiler is just wrong. It didn’t manage to decompile the bit that creates the
SamTwoArg
instance, so it can’t tell that
samTwo
has a non-null value.
I think there are different ways SAM is implemented depending on what version you target, but the decompiler doesn’t seem to do well with any of them in this example
I think the most modern way to do SAM is with the
LambdaMetafactory
, there’s a neat Java example here: https://gist.github.com/alexengrig/df1797d4d07c9f5d521d8c33c2a56563
c
Thanks Sam I will take a look