2017-09-25 93 views
1

據我瞭解科特林應該能夠使用JRE 6運行,但這段代碼有foreach地圖上的失敗,因爲對一個Java 8類(java/util/function/BiConsumer爲什麼Kotlin字節碼引用java.util.function.BiConsumer?

CompilerTest.kt參考:

fun main(args: Array<String>) { 
    val aMap = mapOf("bar" to "bat") 
    aMap.forEach { k, v -> println("$k -> $v")} 
} 

編譯科特林代碼:

» kotlinc CompilerTest.kt -jvm-target 1.6 -include-runtime -d compilerTest.jar 

測試上JRE 6編譯後的代碼:

» docker run --rm -v "$PWD":/usr/src/myapp -w /usr/src/myapp openjdk:6-jdk-slim java -jar compilerTest.jar 
Exception in thread "main" java.lang.NoClassDefFoundError: java/util/function/BiConsumer 
    at java.lang.ClassLoader.defineClass1(Native Method) 
    at java.lang.ClassLoader.defineClass(ClassLoader.java:643) 
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) 
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:277) 
    at java.net.URLClassLoader.access$000(URLClassLoader.java:73) 
    at java.net.URLClassLoader$1.run(URLClassLoader.java:212) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at java.net.URLClassLoader.findClass(URLClassLoader.java:205) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:323) 
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:268) 
    at CompilerTestKt.main(CompilerTest.kt:5) 
Caused by: java.lang.ClassNotFoundException: java.util.function.BiConsumer 
    at java.net.URLClassLoader$1.run(URLClassLoader.java:217) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at java.net.URLClassLoader.findClass(URLClassLoader.java:205) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:323) 
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:268) 
    ... 12 more 

版本信息:

» kotlinc -version   
info: kotlinc-jvm 1.1.4-3 (JRE 1.8.0_131-b11) 

回答

0

kotlinc-JVM 1.1.4-3(JRE 1.8.0_131-B11)

好像你正在使用JDK 8版本。如果你正在使用gradle,你應該檢查你的build.gradle

compile "org.jetbrains.kotlin:kotlin-stdlib" // JDK 6 
compile "org.jetbrains.kotlin:kotlin-stdlib-jre7" // JDK 7 
compile "org.jetbrains.kotlin:kotlin-stdlib-jre8" // JDK 8 
5

原來,kotlin Map繼承自java.util.Map。當您致電aMap.forEach { k, v -> println("$k -> $v")}時,您正在調用該方法的Java version

但是,如果更改代碼以輸入條目:aMap.forEach { entry -> println("$entry.key -> $entry.value")},那麼您調用的是Kotlin version,代碼將在JRE6上運行。

您可以通過編譯-no-jdk標誌來標記對JRE的依賴關係。

» kotlinc CompilerTest.kt -no-jdk -jvm-target 1.6 -include-runtime -d compilerTest.jar 
CompilerTest.kt:5:10: error: type inference failed: inline fun <K, V> Map<out K, V>.forEach(action: (Map.Entry<K, V>) -> Unit): Unit 
cannot be applied to 
receiver: Map<String, String> arguments: ((Map.Entry<String, String>, ???) -> Unit) 

    aMap.forEach { k, v -> println("$k -> $v")} 
     ^
... 
+4

替代地使用'aMap.forEach {(K,V) - >的println( 「$的k - > $ V」)}' - 注意到'(K,V)'。它在原地進行'Entry'分解 – voddan

相關問題