为什么 Go 语言可以交叉编译,打包出目标平台二进制, Java 不行?

2020-07-15 09:13:02 +08:00
 smallyu

好像很多语言的程序包执行都需要相应的环境,除了脚本类的,Java 这种需要编译的,好像经常也是 java -jar abc.jar 这种,而 go 语言能直接编译出不依赖 go 环境的包。可以帮忙提点一下吗盆友们,关于这个问题,应该往哪方面去了解?

7568 次点击
所在节点    程序员
36 条回复
seers
2020-07-15 09:16:07 +08:00
解释型编译型?不过 Java 也要编译但是还是依赖 jvm
HiShan
2020-07-15 09:16:26 +08:00
graalvm 了解一下
sulinehk
2020-07-15 09:17:45 +08:00
可以进行自动垃圾回收的语言都需要一个运行时环境,只不过 Go 是把这个运行时打包到二进制文件里,而 Java 显示使用这个运行时。
ChanKc
2020-07-15 09:18:35 +08:00
aot 和 jit ?
lower
2020-07-15 09:20:29 +08:00
操作系统原理、编译原理、计算机组成原理
monkeyWie
2020-07-15 09:22:12 +08:00
graalvm +1,不过静态编译限制比较多,反射类加载就不好用了
BingoXuan
2020-07-15 09:28:26 +08:00
java 编译出来的是通用的字节码,扔到不同平台的 jvm 内就能运行,实现 compile once, run(debug?) everywhere 。
go 编译出来的是不同平台的机器码,不同平台只能运行对应二进制文件,实现 code once, compile for everywhere
sonxzjw
2020-07-15 09:40:15 +08:00
1.java 也可以打包成二进制执行程序,要找工具,有不少缺点;
2.java 的创始人的层面就是这样的理念,用 jvm ;

其实这些很多都是跟语言创始人的理念、多方面考虑而定的。
zjsxwc
2020-07-15 09:43:43 +08:00
只要 jvm 在目标平台可以跑就行,大不了发布的时候把 jvm 也带上不就好了
tlday
2020-07-15 09:46:44 +08:00
Java 最初就是作为编写放进一些家电设备中的嵌入式编程语言立项的,在这种条件下,你要求这些家电设备内置一个桌面级运行环境是很奢侈的,那可是 1991 年,桌面级运行环境作为嵌入式设备的平台?那个时候还不是这三家独大,有各种奇奇怪怪的系统和平台。相反,你制订一个标准让对应的硬件平台厂商去实现,要更符合那个时代的主旋律。
而且将 runtime 直接放进应用程序这种想法在当时的带宽条件下是个正常人都不会有的。大家肯定还记得在智能手机出现以前,一些支持 J2ME 平台的手机,一个几百 k 的 jar 文件中能有多丰富的游戏内容。如果你把 runtime 也打包进去,那是不可能那么小的。你看 Windows 到现在还在发布.Net
你不能现在只看得到 JavaSE 和 JavaEE 就忽略 J2ME 才是 Java 最早的初衷。
tlday
2020-07-15 09:47:30 +08:00
独立的.Net runtime 到操作系统。
dakb
2020-07-15 09:51:58 +08:00
因为 java 是跑在虚拟机上的语言。go 是直接编译成目标文件的语言。
DJQTDJ
2020-07-15 10:18:33 +08:00
建议楼主私信 James Gosling,我想如果他有时间的话,应该会告诉楼主为什么把
https://twitter.com/errcraft
janxin
2020-07-15 10:30:10 +08:00
不要这样,Java 其实也可以的,GraalVM 了解一下
Rwing
2020-07-15 10:40:14 +08:00
.NET 欢迎您
libook
2020-07-15 10:50:39 +08:00
不知道什么课程里会包含这些知识,计算机导论?感觉只要是科班出身的都自然而然地了解这个。

大学课程里最初是会将编程语言分为:
机器语言:二进制指令
低级编程语言:汇编语言
高级编程语言:C 、C++、Java 等等

然后高级编程语言大体上又可以分为:
编译型语言:C 、C++、Java 等
解释型语言:JavaScript 、Python 、PHP 等

编译型语言又可以分为:
直接编译成平台机器码的语言:C 、C++、Go 等
编译成虚拟机机器码的语言:Java 、C#、WebAssembly 等

以上只代表各个语言的常规使用方式,实际上语言只是语言,设计不同的编译和运行机制,可以让一门语言以不同的方式来操作计算机运行,比如使用特定的编译器可以将 Java 直接编译成机器码,不依赖 Java 运行时就可以运行,C 也可以编译成虚拟机机器码,在虚拟机上运行。

Java 的可执行程序本身不携带 Java 运行环境,这个其实是 Java 的设计初衷,以及其最大的卖点:“Write once, run everywhere”。因为早先的编程语言都需要编译成对应平台的机器码才能被正确运行,比如想在电脑上运行就编译成台式机平台的程序文件,想在手机上运行就编译成手机平台的程序文件,而如果电脑和手机采用的 CPU (指令集)不一样的话,对应电脑平台的可执行文件无法在手机上运行,而且编译成不同平台的程序文件很可能需要改动大量代码。(这个就不展开介绍了,想了解可以去学习一下计算机组成原理和汇编语言。)然后 Java 率先实现了写一份代码、编译成一个可执行文件,可以在任何被 Java 运行环境支持的设备上运行,Sun 公司负责开发出支持各个设备的 Java 运行环境。这对于需要程序支持多个硬件平台的开发者来说,几乎完全免除了兼容多个设备需要做的大量工作(至少在当时是)。
passerbytiny
2020-07-15 10:53:46 +08:00
Go 是用来替代 C ( C ++)的,为何要跟 Java 比较。
Kilerd
2020-07-15 11:37:56 +08:00
@passerbytiny #17 Go 用来替代 C ?
dhssingle
2020-07-15 11:57:14 +08:00
@passerbytiny #17 因为实际跑起来,效率还不如 C# 和 Java,拿什么去替代 C 。
wysnylc
2020-07-15 12:12:28 +08:00
Java 可以,只是不建议用
Go 是只能打包成二进制文件,没有其他选择哦

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/690116

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX