use*_*669 20 java lambda java-8
Lambda是在Java8中引入的.包含lambda表达式的代码是否会在较旧的JVM上运行,例如,对于java 1.6?我担心二进制兼容性而不是源代码兼容性.这是一个简单的是/否问题.
谢谢.
Jör*_*tag 36
Oracle非常努力地将Java语言和JVM字节码语言分开.Java语言规范只说明包含lambda表达式的程序意味着什么,它没有说明该程序应该如何编译或解释.
这意味着Java语言规范中没有任何内容禁止lambda表达式以这样的方式编译,即生成的代码可以由Java 6 JVM执行,但Java语言规范中没有任何内容可以保证它.允许每个Java供应商以他们想要的任何方式编码lambda表达式.(显然,出于实际的原因,大多数尝试匹配Oracle所做的非常接近的事情.这样,例如,可以理解和反向工程由Oracle编码的lambdas的调试器/反编译器/工具javac将自动使用IBM J9生成的字节码JDK的Java编译器.)
在javac该附带的Oracle JDK编码使用lambda表达式的一个相当复杂的机械的编译器LambdaMetafactory,MethodHandle小号和invokedynamic.后者仅在Java 7 JVM中引入,因此这意味着Oracles JDK 使用的特定编码至少需要Java 7 JVM.但其他编码绝对是可能的,这些复杂的机器都不是真正必要的,它只是一种性能优化.你可以将Lambda Expressions编码为内部类,这可以归结为Java 1.1 JVM - 这毕竟是我们编写的"穷人的lambdas"到Java 8的结果.这也是lambda的原始提案甚至Java 8的早期预览如何实现它,毕竟,Java中lambdas的开发甚至早于Java 7和Java 7 .javacinvokedynamic
有一个名为RetroLambda的编译器,它将Oracle JDK生成的Java 8 JVM字节码(不是Java源代码!)编译javac为Java 7 JVM字节码,Java 6 JVM字节码或Java 5 JVM字节码.使用此编译器,您可以生成包含字节码的类文件,该文件代码将在Java 8源代码中运行在任何Java 5或更高版本的JVM上,该源代码使用(几乎)Java 8的所有功能.
Gho*_*ica 16
简答:这取决于.
如果您完全受限于Oracle javac和库,答案是:no; 由于以下原因.
Java字节码包含主要版本号.默认情况下,Java 8编译器将java8放入数据中.任何较旧的JVM都拒绝运行该代码.虽然可以告诉Java 8编译器创建与旧JVM兼容的字节码.但是:为了让旧的JVM执行这样的"特殊"类文件,您需要所有的依赖项都可用!
并且它中断了:Lambdas使用了Java 6中不存在的invokedynamic字节码指令.除此之外,编译器在编译lambda时使用了大量的Java库 - 所有这些都在java 6之后添加.
因此,即使您设法使用源代码将lambda编译为Java 6字节码 - 该指令也不可用,您也需要提供所有其他类.
但是:正如另一个伟大的答案所解释的那样,javac还有其他选择,允许你在旧的JVM上使用lambdas.
但是:小心如何消耗能量.Java 6对于"服务器端java"仍然是死的.因此,对于像Android这样的平台,使用这些替代方案是可以的,但是当您仍在某处运行Oracle Java 6 JVM时,您应该将精力用于将该系统升级到当前版本的Java.
正如其他人所说:不
javac编译器生成的类文件是版本化的.Java 8生成的所有内容都标记为默认需要Java 8 JVM.较旧版本的JVM不接受二进制文件.
如果你想为旧平台编译,你必须告诉javac : javac -target 6. 只要将此选项添加到命令行,Java 8编译器就会要求您指定-source 6(或更低).因此,它不会接受任何包含lambda表达式的代码.
| 归档时间: |
|
| 查看次数: |
1977 次 |
| 最近记录: |