为什么编译后的java不兼容转发

为什么编译后的java不兼容转发,java,jvm,bytecode,Java,Jvm,Bytecode,除非我误解了JVM是如何工作的,否则Java字节码不是与编译的C有点相同,只是它运行在JVM上而不是操作系统上(JVM充当操作系统) 如果是这样,难道这不意味着新的JAR应该能够在我想要的JVM的任何版本上运行吗 或者Java版本之间的实际字节码指令是否存在某种差异,而C等版本中不存在这种差异?否。通常会引入一些实际的(不兼容的)差异来支持新功能(并且总是有一个版本号)。字节码是向后兼容的,因为较旧的编译器编译的字节码可以被较新的环境调用(并链接)(向后)。它不兼容转发,这正是您实际询问的问题。

除非我误解了JVM是如何工作的,否则Java字节码不是与编译的C有点相同,只是它运行在JVM上而不是操作系统上(JVM充当操作系统)


如果是这样,难道这不意味着新的JAR应该能够在我想要的JVM的任何版本上运行吗


或者Java版本之间的实际字节码指令是否存在某种差异,而C等版本中不存在这种差异?

否。通常会引入一些实际的(不兼容的)差异来支持新功能(并且总是有一个版本号)。字节码是向后兼容的,因为较旧的编译器编译的字节码可以被较新的环境调用(并链接)(向后)。它不兼容转发,这正是您实际询问的问题。无论如何,您可以使用
javap-v
检查指令助记符并查看版本


另外,从您的问题来看,(作为一个人为的例子),使用
gcc
编译的代码(可能)不会在
486
386
上运行(与
-mtune
相反)。

否。通常会引入实际的(不兼容的)差异来支持新功能字节码是向后兼容的,因为较旧的编译器编译的字节码可以被较新的环境调用(和链接)(向后)。它不兼容转发,这是您实际询问的问题。无论如何,您可以使用
javap-v
检查指令助记符并查看版本


另外,从您的问题来看,(作为一个人为的例子),使用
gcc
编译的代码(可能)不会在
486
386
上运行(与
-mtune
相反).

它不能向前兼容,因为这意味着不可能引入新的字节码

当java的新版本引入新的字节码时,旧版本的VM自然无法解释该字节码

这意味着java不能向前兼容,因为它维护一组不断发展的(本机)命令

这与C/C++不同。这种语言的编译器会为目标处理器生成字节码。处理器的命令集不会更改,它是静态的。因此,在为特定CPU编译C时,只要有与o/C++标准对应的指令,C/C++标准的每个版本都会编译并运行需要手术



编辑:当你仔细观察时,这个问题也可以在C/C++中看到。例如,标题
引入了可选的类型,例如
int64\u t
。这是出于向前兼容的原因。较旧的芯片可能无法处理64位整数类型,因此为了保持这些类型的向前兼容,标准使它们可以选择声明。

它不向前兼容,因为这意味着不可能引入新的字节码

当java的新版本引入新的字节码时,旧版本的VM自然无法解释该字节码

这意味着java不能向前兼容,因为它维护一组不断发展的(本机)命令

这与C/C++不同。这种语言的编译器会为目标处理器生成字节码。处理器的命令集不会更改,它是静态的。因此,在为特定CPU编译C时,只要有与o/C++标准对应的指令,C/C++标准的每个版本都会编译并运行需要手术



编辑:当你仔细观察时,这个问题也可以在C/C++中看到。例如,标题
引入了可选的类型,例如
int64\u t
。这是出于向前兼容的原因。较旧的芯片可能无法处理64位整数类型,因此为了保持这些类型的向前兼容,标准使它们可以选择声明。

“新的JAR应该能够在我想要的任何JVM版本上运行”这不是向前兼容吗?@PaulBellora除非我弄错了,向前兼容意味着旧JAR仍然可以在新的jvm上运行,不是吗?如果我使用C++14编码和编译一个程序,你会说它向后兼容,因为它将在任何系统上运行,而不管版本(我认为)有一个术语“新的JAR应该能够在我想要的JVM的任何版本上运行“这不是向前兼容吗?@PaulBellora除非我弄错了,向前兼容意味着旧JAR仍然可以在新的jvm上运行,不是吗?如果我使用C++14编码和编译一个程序,你会说它向后兼容,因为它将在任何系统上运行,而不管版本如何(我想)在您的示例中有一个术语,不兼容是来自语言级别?还是因为奔腾的体系结构不同?因为据我的理解(可能是错误的)但是让我们说我用C++ C++编写了一些东西并编译它,它将运行在C++的任何版本上,因为实际的指令是相同的。@ TimeBeGeEeSein以字节码的形式出现。我认为它(大部分)是工作的。我可以想到一些不向后兼容的改变。(但是使用带有sane接口的jar文件,不进行任何字节码操作通常是有效的)。@Epicblood JVM的体系结构可以(有时也可以)版本之间的变化。@提姆:怎么?我知道的唯一向后的不兼容的改变是删除AccSub,这是一个非常令人困惑的特性,它只被引入到一个早期编译器错误的工作中。@ EpICHOLL:“它将运行在C++的任何版本上”。没有意义。编译的C++代码不运行在<代码> C++ +/COD>版本上。它运行在一个CPU上,编译后的CPU将不会在一个旧CPU上运行。java源代码COD同样如此。