Kotlin反编译器为何生成null.INSTANCE

Kotlin反编译器为何生成null.INSTANCE,kotlin,jvm-bytecode,Kotlin,Jvm Bytecode,我试图通过检查Kotlin在Java端的外观来了解它的一些特性 作为一个实验,我尝试了以下方法: val printKotlin = fun () { print("Hello Kotlin") } 因此,上述代码段的输出为: public final class FunAsVariableKt { private static final Function0 printKotlin; public static final Function0 getPrintKot

我试图通过检查Kotlin在Java端的外观来了解它的一些特性

作为一个实验,我尝试了以下方法:

val printKotlin = fun () {
    print("Hello Kotlin")
}
因此,上述代码段的输出为:

public final class FunAsVariableKt {
    private static final Function0 printKotlin;

    public static final Function0 getPrintKotlin() {
        return printKotlin;
    }

    static {
        printKotlin = (Function0)null.INSTANCE;
    }
}

如何理解上述反编译代码的静态块?为什么要生成这种不工作的代码?

使用Kotlin字节码检查器查看生成的JVM字节码,而不是尝试将字节码反编译为Java,这可能不适用于其他语言编译器生成的代码,因为它可能不符合预期的模式。字节码反编译器并不总是生成工作代码

JVM字节码!=特定于Java语言

Kotlin生成的JVM字节码!=Java生成的JVM字节码

您看到的空实例是反编译器的错误解释,您可以看到字节码中对
instance
的所有引用都正确设置了值

这是实际输出:

// ================Stackoverflow_53384931Kt.class =================
// class version 52.0 (52)
// access flags 0x31
public final class Stackoverflow_53384931Kt {


  // access flags 0x1A
  // signature Lkotlin/jvm/functions/Function0<Lkotlin/Unit;>;
  // declaration: kotlin.jvm.functions.Function0<kotlin.Unit>
  private final static Lkotlin/jvm/functions/Function0; printKotlin
  @Lorg/jetbrains/annotations/NotNull;() // invisible

  // access flags 0x19
  // signature ()Lkotlin/jvm/functions/Function0<Lkotlin/Unit;>;
  // declaration: kotlin.jvm.functions.Function0<kotlin.Unit> getPrintKotlin()
  public final static getPrintKotlin()Lkotlin/jvm/functions/Function0;
  @Lorg/jetbrains/annotations/NotNull;() // invisible
   L0
    LINENUMBER 3 L0
    GETSTATIC Stackoverflow_53384931Kt.printKotlin : Lkotlin/jvm/functions/Function0;
    ARETURN
   L1
    MAXSTACK = 1
    MAXLOCALS = 0

  // access flags 0x8
  static <clinit>()V
   L0
    LINENUMBER 3 L0
    GETSTATIC Stackoverflow_53384931Kt$printKotlin$1.INSTANCE : LStackoverflow_53384931Kt$printKotlin$1;
    CHECKCAST kotlin/jvm/functions/Function0
    PUTSTATIC Stackoverflow_53384931Kt.printKotlin : Lkotlin/jvm/functions/Function0;
    RETURN
    MAXSTACK = 1
    MAXLOCALS = 0

  @Lkotlin/Metadata; ... 
  // access flags 0x18
  final static INNERCLASS Stackoverflow_53384931Kt$printKotlin$1 null null
  // compiled from: stackoverflow-53384931.kt
}


// ================Stackoverflow_53384931Kt$printKotlin$1.class =================
// class version 52.0 (52)
// access flags 0x30
// signature Lkotlin/jvm/internal/Lambda;Lkotlin/jvm/functions/Function0<Lkotlin/Unit;>;
// declaration: Stackoverflow_53384931Kt$printKotlin$1 extends kotlin.jvm.internal.Lambda implements kotlin.jvm.functions.Function0<kotlin.Unit>
final class Stackoverflow_53384931Kt$printKotlin$1 extends kotlin/jvm/internal/Lambda  implements kotlin/jvm/functions/Function0  {


  // access flags 0x1041
  public synthetic bridge invoke()Ljava/lang/Object;
    ALOAD 0
    INVOKEVIRTUAL Stackoverflow_53384931Kt$printKotlin$1.invoke ()V
    GETSTATIC kotlin/Unit.INSTANCE : Lkotlin/Unit;
    ARETURN
    MAXSTACK = 1
    MAXLOCALS = 1

  // access flags 0x11
  public final invoke()V
   L0
    LINENUMBER 4 L0
    LDC "Hello Kotlin"
    ASTORE 1
   L1
    GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
    ALOAD 1
    INVOKEVIRTUAL java/io/PrintStream.print (Ljava/lang/Object;)V
   L2
   L3
    LINENUMBER 5 L3
    RETURN
   L4
    LOCALVARIABLE this LStackoverflow_53384931Kt$printKotlin$1; L0 L4 0
    MAXSTACK = 2
    MAXLOCALS = 2

  // access flags 0x0
  <init>()V
    ALOAD 0
    ICONST_0
    INVOKESPECIAL kotlin/jvm/internal/Lambda.<init> (I)V
    RETURN
    MAXSTACK = 2
    MAXLOCALS = 1

  // access flags 0x19
  public final static LStackoverflow_53384931Kt$printKotlin$1; INSTANCE

  // access flags 0x8
  static <clinit>()V
    NEW Stackoverflow_53384931Kt$printKotlin$1
    DUP
    INVOKESPECIAL Stackoverflow_53384931Kt$printKotlin$1.<init> ()V
    PUTSTATIC Stackoverflow_53384931Kt$printKotlin$1.INSTANCE : LStackoverflow_53384931Kt$printKotlin$1;
    RETURN
    MAXSTACK = 2
    MAXLOCALS = 0

  @Lkotlin/Metadata; ...
  OUTERCLASS Stackoverflow_53384931Kt null
  // access flags 0x18
  final static INNERCLASS Stackoverflow_53384931Kt$printKotlin$1 null null
  // compiled from: stackoverflow-53384931.kt
  // debug info: SMAP
  ...

}
/=========================Stackoverflow_53384931Kt.class=================
//课程版本52.0(52)
//访问标志0x31
公共最终等级53384931Kt{
//访问标志0x1A
//签名Lkotlin/jvm/functions/Function0;
//声明:kotlin.jvm.functions.Function0
私有最终静态Lkotlin/jvm/functions/Function0;printKotlin
@Lorg/jetbrains/annotations/NotNull;()//不可见
//访问标志0x19
//签名()Lkotlin/jvm/functions/Function0;
//声明:kotlin.jvm.functions.Function0 getPrintKotlin()
公共最终静态getPrintKotlin()Lkotlin/jvm/functions/Function0;
@Lorg/jetbrains/annotations/NotNull;()//不可见
L0
行号3 L0
GETSTATIC Stackoverflow_53384931Kt.printKotlin:Lkotlin/jvm/functions/Function0;
轮回
L1
MAXSTACK=1
最大局部变量=0
//访问标志0x8
静态()V
L0
行号3 L0
GETSTATIC Stackoverflow_53384931Kt$printKotlin$1.INSTANCE:LStackoverflow_53384931Kt$printKotlin$1;
CHECKCAST kotlin/jvm/functions/Function0
PUTSTATIC Stackoverflow_53384931Kt.printKotlin:Lkotlin/jvm/functions/Function0;
回来
MAXSTACK=1
最大局部变量=0
@Lkotlin/Metadata。。。
//访问标志0x18
最终静态内部类Stackoverflow_53384931Kt$printKotlin$1 null
//编译自:stackoverflow-53384931.kt
}
//=====================Stackoverflow_53384931Kt$printKotlin$1.5级=================
//课程版本52.0(52)
//访问标志0x30
//签名Lkotlin/jvm/internal/Lambda;Lkotlin/jvm/functions/Function0;
//声明:Stackoverflow_53384931Kt$printKotlin$1扩展了kotlin.jvm.internal.Lambda实现了kotlin.jvm.functions.Function0
最后一个类Stackoverflow_53384931Kt$printKotlin$1扩展了kotlin/jvm/internal/Lambda实现了kotlin/jvm/functions/Function0{
//访问标志0x1041
公共合成桥invoke()Ljava/lang/Object;
阿洛德0
INVOKEVIRTUAL Stackoverflow_53384931Kt$printKotlin$1.invoke()V
GETSTATIC kotlin/Unit.INSTANCE:Lkotlin/Unit;
轮回
MAXSTACK=1
最大局部数=1
//访问标志0x11
公共最终调用()V
L0
线路号4 L0
LDC“你好,科特林”
阿斯托尔1号
L1
GETSTATIC java/lang/System.out:Ljava/io/PrintStream;
阿洛德1号
invokeVirtualJava/io/PrintStream.print(Ljava/lang/Object;)V
L2
L3
线路号5 L3
回来
L4
LOCALVARIABLE此LStackoverflow_53384931Kt$printKotlin$1;L0 L4 0
MAXSTACK=2
最大局部数=2
//访问标志0x0
()V
阿洛德0
ICONST_0
调用特殊的kotlin/jvm/internal/Lambda.(I)V
回来
MAXSTACK=2
最大局部数=1
//访问标志0x19
公共最终静态LStackoverflow_53384931Kt$printKotlin$1;实例
//访问标志0x8
静态()V
新Stackoverflow_53384931Kt$printKotlin$1
重复
调用特殊Stackoverflow_53384931Kt$printKotlin$1.()V
PUTSTATIC Stackoverflow_53384931Kt$printKotlin$1。实例:LStackoverflow_53384931Kt$printKotlin$1;
回来
MAXSTACK=2
最大局部变量=0
@Lkotlin/Metadata。。。
外部类堆栈溢出_53384931Kt空
//访问标志0x18
最终静态内部类Stackoverflow_53384931Kt$printKotlin$1 null
//编译自:stackoverflow-53384931.kt
//调试信息:SMAP
...
}

使用Kotlin字节码检查器查看作为JVM字节码生成的内容,而不是尝试将字节码反编译为Java,这可能不适用于其他语言编译器生成的代码,因为它可能不符合预期的模式。字节码反编译器并不总是生成工作代码

JVM字节码!=特定于Java语言

Kotlin生成的JVM字节码!=Java生成的JVM字节码

您看到的空实例是反编译器的错误解释,您可以看到字节码中对
instance
的所有引用都正确设置了值

这是实际输出:

// ================Stackoverflow_53384931Kt.class =================
// class version 52.0 (52)
// access flags 0x31
public final class Stackoverflow_53384931Kt {


  // access flags 0x1A
  // signature Lkotlin/jvm/functions/Function0<Lkotlin/Unit;>;
  // declaration: kotlin.jvm.functions.Function0<kotlin.Unit>
  private final static Lkotlin/jvm/functions/Function0; printKotlin
  @Lorg/jetbrains/annotations/NotNull;() // invisible

  // access flags 0x19
  // signature ()Lkotlin/jvm/functions/Function0<Lkotlin/Unit;>;
  // declaration: kotlin.jvm.functions.Function0<kotlin.Unit> getPrintKotlin()
  public final static getPrintKotlin()Lkotlin/jvm/functions/Function0;
  @Lorg/jetbrains/annotations/NotNull;() // invisible
   L0
    LINENUMBER 3 L0
    GETSTATIC Stackoverflow_53384931Kt.printKotlin : Lkotlin/jvm/functions/Function0;
    ARETURN
   L1
    MAXSTACK = 1
    MAXLOCALS = 0

  // access flags 0x8
  static <clinit>()V
   L0
    LINENUMBER 3 L0
    GETSTATIC Stackoverflow_53384931Kt$printKotlin$1.INSTANCE : LStackoverflow_53384931Kt$printKotlin$1;
    CHECKCAST kotlin/jvm/functions/Function0
    PUTSTATIC Stackoverflow_53384931Kt.printKotlin : Lkotlin/jvm/functions/Function0;
    RETURN
    MAXSTACK = 1
    MAXLOCALS = 0

  @Lkotlin/Metadata; ... 
  // access flags 0x18
  final static INNERCLASS Stackoverflow_53384931Kt$printKotlin$1 null null
  // compiled from: stackoverflow-53384931.kt
}


// ================Stackoverflow_53384931Kt$printKotlin$1.class =================
// class version 52.0 (52)
// access flags 0x30
// signature Lkotlin/jvm/internal/Lambda;Lkotlin/jvm/functions/Function0<Lkotlin/Unit;>;
// declaration: Stackoverflow_53384931Kt$printKotlin$1 extends kotlin.jvm.internal.Lambda implements kotlin.jvm.functions.Function0<kotlin.Unit>
final class Stackoverflow_53384931Kt$printKotlin$1 extends kotlin/jvm/internal/Lambda  implements kotlin/jvm/functions/Function0  {


  // access flags 0x1041
  public synthetic bridge invoke()Ljava/lang/Object;
    ALOAD 0
    INVOKEVIRTUAL Stackoverflow_53384931Kt$printKotlin$1.invoke ()V
    GETSTATIC kotlin/Unit.INSTANCE : Lkotlin/Unit;
    ARETURN
    MAXSTACK = 1
    MAXLOCALS = 1

  // access flags 0x11
  public final invoke()V
   L0
    LINENUMBER 4 L0
    LDC "Hello Kotlin"
    ASTORE 1
   L1
    GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
    ALOAD 1
    INVOKEVIRTUAL java/io/PrintStream.print (Ljava/lang/Object;)V
   L2
   L3
    LINENUMBER 5 L3
    RETURN
   L4
    LOCALVARIABLE this LStackoverflow_53384931Kt$printKotlin$1; L0 L4 0
    MAXSTACK = 2
    MAXLOCALS = 2

  // access flags 0x0
  <init>()V
    ALOAD 0
    ICONST_0
    INVOKESPECIAL kotlin/jvm/internal/Lambda.<init> (I)V
    RETURN
    MAXSTACK = 2
    MAXLOCALS = 1

  // access flags 0x19
  public final static LStackoverflow_53384931Kt$printKotlin$1; INSTANCE

  // access flags 0x8
  static <clinit>()V
    NEW Stackoverflow_53384931Kt$printKotlin$1
    DUP
    INVOKESPECIAL Stackoverflow_53384931Kt$printKotlin$1.<init> ()V
    PUTSTATIC Stackoverflow_53384931Kt$printKotlin$1.INSTANCE : LStackoverflow_53384931Kt$printKotlin$1;
    RETURN
    MAXSTACK = 2
    MAXLOCALS = 0

  @Lkotlin/Metadata; ...
  OUTERCLASS Stackoverflow_53384931Kt null
  // access flags 0x18
  final static INNERCLASS Stackoverflow_53384931Kt$printKotlin$1 null null
  // compiled from: stackoverflow-53384931.kt
  // debug info: SMAP
  ...

}
/=========================Stackoverflow_53384931Kt.class=================
//课程版本52.0(52)
//访问标志0x31
公共最终等级53384931Kt{
//访问标志0x1A
//签名Lkotlin/jvm/functions/Function0;
//声明:kotlin.jvm.functions.Function0
私有最终静态Lkotlin/jvm/functions/Function0;printKotlin
@Lorg/jetbrains/annotations/NotNull;()//不可见
//访问标志0x19
//签名()Lkotlin/jvm/functions/Function0;
//声明:kotlin.jvm.functions.Function0 getPrintKotlin()
公共最终静态getPrintKotlin()Lkotlin/jvm/functions/Function0;
@Lorg/jetbrains/annotations/NotNull;()//不可见
L0
行号3 L0
GETSTATIC Stackoverflow_53384931Kt.printKotlin:Lkotlin/jvm/functions/Function0;
轮回
L1
MAXSTACK=1
最大局部变量=0
//访问标志0x8
静态()V
L0
行号3 L0
GETSTATIC Stackoverflow_53384931Kt$printKotlin$1.INSTANCE:LStackoverflow_53384931Kt$printKotlin$1;
CHECKCAST kotlin/
public final class TryingOutLambdas {


    public final void performSomething() {
        
       takingAOnclickListener(TryingOutLambdas$performSomething$1
        .INSTANCE);
    }

    public final void takingAOnclickListener(@NotNull Function1 onClickListener) {
        Intrinsics.checkParameterIsNotNull(onClickListener, "onClickListener");
        onClickListener.invoke(Integer.valueOf(6));
    }

    static final class TryingOutLambdas$performSomething$1 extends Lambda implements Function1<Integer, String> {
        public static final TryingOutLambdas$performSomething$1 INSTANCE = new TryingOutLambdas$performSomething$1();
        
        @NotNull
        public final String invoke(int x) {
          String str = "Hello " + x;
          boolean bool = false;
          System.out.print(str);
          return Unit.INSTANCE.toString();
        }
        
        TryingOutLambdas$performSomething$1() {
          super(1);
        }
    } 

}