簡體   English   中英

為什么這段代碼不能運行,是 Kotlin 中的一個錯誤嗎?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM