2017-09-25 74 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

相关问题