浅谈java的平台无关性
(上图引自《Java经典入门教程》)
事先说明哈,以下仅代表当前个人理解:
说java是平台无关的语言,我觉得可能会让人误解了一些东西,自己之前就一直搞不懂java所谓的平台无关性是怎样的或者怎么实现的。这里,说一下自己这阵子java学习之后对于这个概念的理解:首先,我认为所谓的语言平台无关性,其实对于所有高级编程语言(如C/C++、java)来说,都是平台无关的,因为高级编程语言是用来在人和机器之间搭建更简便的沟通的方式,或者说更偏向于让人来理解的,最终无论哪种语言,都是要转化成0101的机器码的。这中间有一个很关键的步骤,我觉得就是平台无关性的真正所在,那就是从高级编程语言到0101机器码中间的转换,我们知道,高级编程语言需要先编译转换成低级编程语言:汇编语言,汇编语言就是诸如:CPU,来,你给我去把ram里面的两段数据A、B拿去相加,然后把相加的结果帮我存回ram的某个地址空间。然后汇编语言再经过“汇编阶段”把汇编语言转换成0101的机器码。问题就在于两层的转换了,首先,编译器不同,就可能会导致高级编程语言转换成机器码中间两层就出现不同,比如编译器a对于一个高级语言做加法(纯属虚构假设):a + b = ?最终会转换成 100100100但是编译器b则会将它转换成 111000111
然后又一个关键的问题来了,C/C++编出来的程序往往是直接把可执行文件,也就是0101的机器码传输给各种机器来跑,那么我编译器编译出来的100100100,机器A能正常识别并正常执行,但是机器B里面设定的规则是a + b = ? 你只能给我转换成111000111我才能正常识别并正常执行,现在你给我扔一堆100100100,这样会咋办?要么根本无法执行,要么CPU流水线执行出来的结果跟预期的截然不同。这样就带来了平台有关性。那么你就会说了,为什么CPU厂商和编译器开发者(这两者貌似一般是同个公司干的例如intel)要弄这么多套规则出来而不是订一套规范出来大家统一那样做呢。原因很多,总之现实就是没这样做。然后我们会发现一点,对于C/C++这些高级语言来说,语言本身是平台无关的,它只是方便人们去描述机器要干的事情。只是最终转换成机器语言的时候,会产生分支导致不同。好比如说人类要跟动物交流,人类想表达“你今天吃饭了没”,
拿这个问题去问青蛙,那么你得跟它说蛙语:哇哇哇,呱呱呱。你再拿这个问题去问小鸟,那么你得跟它说鸟语:叽叽,叽叽~。有个大家都期待的解决办法也一劳永逸的办法是,咋不让青蛙和小鸟都学会听人类的语言呢?那么我用同样的一句话,它们就都能听懂了。但是现实是,不仅动物之间,人类之间,各个国家甚至一个地级市里面,都有很多种不同的语言。这里面的原因很复杂,总之现状就是这样。既然现状是如此,那么java是怎么解决这个问题的呢?
java运用了一个很朴素的思想,那就是:我是人类,我这么聪明,干嘛我非得每次都重复同样的意思去表达一句话啊,不行,我得开发一个翻译机,我说人话:你今天吃饭了没,这机子就会自动帮我转换,当青蛙来了,这机子就会帮我转换成蛙语:哇哇哇,呱呱呱。当小鸟又来了,它又会帮我转换成鸟语:叽叽,叽叽~对,也就是树形结构或者说中间层这个思想。一个树有个根节点,它是圆筒的,然后它有多个分叉,分叉1是方筒的,分叉2是葫芦状的,以此类推。然后流水下来了,从根节点的圆筒开始进来,
然后流到了各个分支,不管是方筒的,还是葫芦状的还是啥,它们都能帮根节点把这水分流到底层的各个终端。而中间层的思想就是java它帮我们屏蔽了下层的硬件相关性,那就是一个很强大的java虚拟机,就像一个椅子,我不管它下面是多少个脚或者说它用砖头还是木头摆起来的,我只关注一点:让我坐的是平坦的一个软垫。java虚拟机就是这张椅子,它帮我们搞定了下层硬件相关的东西,对你也屏蔽了这些东西,你只需要坐上这个去到哪都一个样的平坦软垫,然后在上面写.java文件编java程序就行了。那么问题来了,我个人认为,对java虚拟机来说,它是硬件相关的,它的设计需要根据实际的硬件情况而定。所以java虚拟机不是全世界就一个版本,它有多个版本,但是只要你给你的机器安装了正确可用的虚拟机版本,那你上面写java程序就完全不用担心硬件相关的东西了。就像我接触到的java智能卡,它用的虚拟机就是定制版本的,虚拟机地下的操作系统也是定制版本的。你得让它们去关注硬件相关的东西,去匹配芯片。也就是说,相比于C/C++拿一堆0101的机器码到处跑,跑到中国有人认识你,但是跑到美国别人就不认识你了。而java它是生成中间代码:字节码,这个字节码是统一的,然后再把这个字节码丢给这台机子上的虚拟机跑,只要虚拟机能吻合机器,那我的字节码就能跑。所以C/C++能不能我也带着一份大家都能认识的中间代码出去?不好意思,你别改我的C/C++,那是我设计的。所以C#就出来了,C#它是参考了java的。
所以,相比说java是平台无关语言,我想这句话更不容易让人陷入困扰:
“Write once, run anywhere.”
编写一次.java程序,跨平台运行之。
维基百科对这句话的解释: