我试图通过检查Java方面的外观来了解Kotlin的一些功能。
因此,作为实验,我尝试了以下方法:
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;
}
}
我如何理解上述反编译代码的静态块?为什么会生成此无效代码?
答案 0 :(得分:6)
使用Kotlin字节码检查器查看以JVM字节码形式生成的内容,而不是尝试将字节码反编译为Java,这可能不适用于其他语言编译器生成的代码,因为它可能未遵循预期的模式。字节码反编译器并不总是生成工作代码。
JVM字节码!= Java语言特定
Kotlin生成的JVM字节码!= Java生成的JVM字节码
您看到的NULL实例是反编译器的错误解释,您可以看到字节码中对str.gsub(/({{2,3}\s*)([^{}]*)(\s*}{2,3})/) { |_| $~[1]+Base64.urlsafe_encode64($~[2].strip, padding: false)+$~[3] }
的所有引用都正确地设置了值。
这是实际输出:
INSTANCE
答案 1 :(得分:0)
您可以为此使用JD-GUI。
http://java-decompiler.github.io/
与内置的IntelliJ反编译插件相比,这对我来说效果更好。您只需要将* .class文件提供给它即可。
科林代码
//TryingOutLamdas.kt
class TryingOutLambdas {
public fun performSomething()
{
takingAOnclickListener { x -> print("Hello $x").toString() }
}
fun takingAOnclickListener(onClickListener: (Int) -> (String))
{
onClickListener.invoke(6)
}
}
使用JD-GUI为此进行了转换的字节码。
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);
}
}
}
如果lambda表达式从其声明的函数访问任何变量,则将创建一个实现该接口的新对象,而不是创建上面创建的Singleton实例。