[英]Why can't this code run, is it a bug in Kotlin?
我寫了一段代碼,然后編譯沒有錯誤。 但是當我運行時,它拋出一個異常(java.lang.NoClassDefFoundError: TesKt$test$1$1)。
這是語言錯誤嗎?
private fun test(block:()->Unit) = arrayOf(1).map {
object {
fun print() {
println("Hello print")
block()
}
}
}
fun main(args: Array<String>) {
val array = test{println("Hello main")}
array[0].print()
}
我將得出結論,這是 Kotlin 編譯器中的一個錯誤。 我對這段代碼玩了很多,並查看了編譯后的字節碼。 似乎編譯器正在丟失一些有關object
定義的匿名類的信息。
如果我們向該對象添加類型,則它可以正常工作:
interface Printable {
fun print()
}
private fun test(block:()->Unit): List<Printable> {
return arrayOf(1).map {
object: Printable {
override fun print() {
println("Hello print")
block()
}
}
}
}
fun main(args: Array<String>) {
val array = test{println("Hello main")}
array[0].print()
}
如您所見,我只定義了一個簡單的Printable
接口,並使用此接口注釋匿名類。
讓我們稱您的代碼為:版本A
,而我的這段代碼為:版本B
。
我編譯了代碼A
然后將其反編譯為Java
。 結果如下:
import TestKt.test.1.1;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import kotlin.Metadata;
import kotlin.Unit;
import kotlin.jvm.functions.Function0;
import kotlin.jvm.internal.Intrinsics;
import org.jetbrains.annotations.NotNull;
@Metadata(
mv = {1, 1, 15},
bv = {1, 0, 3},
k = 2,
d1 = {"\u0000#\n\u0000\n\u0002\u0010\u0002\n\u0000\n\u0002\u0010\u0011\n\u0002\u0010\u000e\n\u0002\b\u0002\n\u0002\u0010 \n\u0002\b\u0002\n\u0002\u0018\u0002*\u0001\b\u001a\u0019\u0010\u0000\u001a\u00020\u00012\f\u0010\u0002\u001a\b\u0012\u0004\u0012\u00020\u00040\u0003¢\u0006\u0002\u0010\u0005\u001a\u001c\u0010\u0006\u001a\b\u0012\u0004\u0012\u00020\b0\u00072\f\u0010\t\u001a\b\u0012\u0004\u0012\u00020\u00010\nH\u0002"},
d2 = {"main", "", "args", "", "", "([Ljava/lang/String;)V", "test", "", "TestKt$test$1$1", "block", "Lkotlin/Function0;"}
)
public final class TestKt {
/*#19:*/private static final List<1> test(Function0<Unit> block) {
Object[] $this$map$iv = new Integer[]{1};
int $i$f$map = false;
Collection destination$iv$iv = (Collection)(new ArrayList($this$map$iv.length));
int $i$f$mapTo = false;
Integer[] var6 = $this$map$iv;
int var7 = $this$map$iv.length;
for(int var8 = 0; var8 < var7; ++var8) {
Object item$iv$iv = var6[var8];
int it = ((Number)item$iv$iv).intValue();
int var11 = false;
/*#31:*/ TestKt.test..inlined.map.lambda.1 var13 = new TestKt.test..inlined.map.lambda.1(block);
destination$iv$iv.add(var13);
}
return (List)destination$iv$iv;
}
public static final void main(@NotNull String[] args) {
Intrinsics.checkParameterIsNotNull(args, "args");
List array = test((Function0)TestKt.main.array.1.INSTANCE);
/*#41:*/((1)array.get(0)).print();
}
}
這是代碼B
相同過程的結果:
import TestKt.test..inlined.map.lambda.1;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import kotlin.Metadata;
import kotlin.Unit;
import kotlin.jvm.functions.Function0;
import kotlin.jvm.internal.Intrinsics;
import org.jetbrains.annotations.NotNull;
@Metadata(
mv = {1, 1, 15},
bv = {1, 0, 3},
k = 2,
d1 = {"\u0000\"\n\u0000\n\u0002\u0010\u0002\n\u0000\n\u0002\u0010\u0011\n\u0002\u0010\u000e\n\u0002\b\u0002\n\u0002\u0010 \n\u0002\u0018\u0002\n\u0000\n\u0002\u0018\u0002\u001a\u0019\u0010\u0000\u001a\u00020\u00012\f\u0010\u0002\u001a\b\u0012\u0004\u0012\u00020\u00040\u0003¢\u0006\u0002\u0010\u0005\u001a\u001c\u0010\u0006\u001a\b\u0012\u0004\u0012\u00020\b0\u00072\f\u0010\t\u001a\b\u0012\u0004\u0012\u00020\u00010\nH\u0002"},
d2 = {"main", "", "args", "", "", "([Ljava/lang/String;)V", "test", "", "LPrintable;", "block", "Lkotlin/Function0;"}
)
public final class TestKt {
/*#19:*/private static final List<Printable> test(Function0<Unit> block) {
Object[] $this$map$iv = new Integer[]{1};
int $i$f$map = false;
Collection destination$iv$iv = (Collection)(new ArrayList($this$map$iv.length));
int $i$f$mapTo = false;
Integer[] var6 = $this$map$iv;
int var7 = $this$map$iv.length;
for(int var8 = 0; var8 < var7; ++var8) {
Object item$iv$iv = var6[var8];
int it = ((Number)item$iv$iv).intValue();
int var11 = false;
/*#31:*/ 1 var13 = new 1(block);
destination$iv$iv.add(var13);
}
return (List)destination$iv$iv;
}
public static final void main(@NotNull String[] args) {
Intrinsics.checkParameterIsNotNull(args, "args");
List array = test((Function0)TestKt.main.array.1.INSTANCE);
/*#41:*/((Printable)array.get(0)).print();
}
}
如您所見,唯一的區別在於第一行,以及行號 19、31 和 41(注釋如#19:
等)。
在代碼A
,需要名稱為1
的類型(奇怪)。 但是這種打包為TestKt.test.1.1
類型1
沒有找到,所以你得到了你的錯誤( NoClassDefFoundError: TesKt$test$1$1
)。
但是,Inn 代碼B
可以預期並找到更清晰的Printable
類型。
如果編譯器像代碼B
一樣編譯了代碼A
第一行( import TestKt.test..inlined.map.lambda.1;
而不是import TestKt.test.1.1;
),那么你的代碼就可以工作了。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.