本章主题:从骨子里看Java的跨平台;本文内容部分摘自https://www.cnblogs.com/roger-yu/p/5827452.html

  有过基础Java知识的开发人员都知道Java是跨平台的,可我们知道Java为什么要跨平台吗,Java的跨平台又是如何实现的呢?下面我们来一一了解。

1.什么是平台

  Java是可以跨平台的编程语言,那我们首先得知道什么是平台,Java是一个高级开发语言,通过操作系统提供的接口进行开发,所以这里的平台主要指的就是操作系统了。

  操作系统是充当用户和计算机之间交互的界面软件,不同的操作系统支持不同的CPU,严格意义上说是不同的操作系统支持不同CPU的指令集。例如  windows和liunx都支持Intel和AMD的复杂指令集,但并不支持PowerPC所使用的精简指令集,而早期的MAC电脑使用的是PowerPC处理器,所以也就无法在MAC下直接安装windows,直到05年MAC改用了Intel的CPU,才使在MAC下安装windows成为可能。但问题来了,原来的MAC 操作系统也只支持PowerPC,在Intel上也不能安装,怎么办?所以苹果公司也得重写自己的MAC操作系统以支持这种变化。最后总结下,我们要知道,不同的操作系统支持不同的CPU指令集,现在的windows,liunx,mac,solaris都支持Intel与AMD的CPU指令集。

  有了上面的铺垫,下面就要告诉大家,如果您要开发程序,首先应该确定自己使用的什么操作系统,知道什么是平台,我们看Java跨平台原理。

2.Java跨平台的原理

  首先看一张与C语言有关的图:   

  如果您有过C的开发经历,这张图看起来将非常轻松。我们知道,只要是用标准C开发的程序,使用不同的编译器【编译器:将一种语言规范转化为另一种语言规范,通常编译器是将便于人们理解的语言规范转化为机器容易理解的语言规范。例如,我们将C语言的语言规范转换为平台的语言规范(能够被平台识别的指令集),这是C语言编译器所做的事情】编译后的可执行文件是可以在对应平台运行的,比如windows可以使用VC编译,那编译后的exe文件就可以在windows下运行;liunx下可以使用GCC编译,生成的可执行文件就可以在Liunx上运行。到这里请大家思考一个问题:“VC编译的exe能在Liunx上运行吗?”

  答案肯定是否定的。使用特定编译器编译的程序只能在对应的平台运行,这里也可以说编译器是与平台相关的,编译后的文件是与平台相关的。我们说的语言跨平台是编译前的文件跨平台【跨平台分为源码级的跨平台和中间码的跨平台】,而不是源程序跨平台,如果是源程序,任何一门语言都是跨平台的语言了。这个如果您不明白,看下面一个案例:比如火星真的有外星人(并且毋庸置疑,火星是韩国人的,火星文也一定是韩国人发明的),就像我们观察蚂蚁一样,火星人默默的观察着我们,有一天,当人类做的 什么事情让火星人实在是看不下去了(比如你的单纯遇上可恶的拜金),所以决定来地球教育我们,但有一个问 题,火星人只会说火星文,地球人理解不了,怎么办啊?找翻译呗(也许非主流可以帮忙,玩笑)!由中文翻译把火星文翻译为中文,英文翻译把火星文翻译为英文 等等等等,但这样问题来了,中文翻译翻译的东西只有中国人能听懂,美国人法国人根本不明白,英文翻译翻译的文章中国人也不明白,也就是语言不能跨平台。

  那上例中,火星文就是C语言,各个国家是平台,中文翻译英文翻译就是对应平台的编译器,编译后的文章就是可执行文件。虽然源文章火星文是与平台无关的,但翻译器是与特定国家相关的,翻译后的文章也是与特定国家相关的。接下来思考另一个问题“怎么让火星文跨平台呢?”

  火星人想到了地球上有世界语,于是首先把自己的文章翻译为世界语;世界语各国人当然看不懂,没关系,火星人又给每个国家配备了一个世界语到本地语的翻译,这 样火星文只要翻译一次(翻译为世界语),就可以到各个国家运行了。还要记住,这个过程火星人要提供两个组件,第一是火星文到世界语的翻译,第二是世界语到对应本地语言的翻译。如下图:

  有了上面案例的积累,我们也知道了语言跨平台原理:“不能编译成机器语言,因为那样就与平台相关了,编译为中间语言,再由解释器二次编译,解释执行。”如下是Java跨平台原理表示图:

  上图中的.java就是源程序,类似于c语言的.c,生成的中间码是.class,这个既是我们上文中说的中间语,各个平台解释器就是各种国家翻译。

接下来我们再比较下两种方式的差异:

  • 第一,C语言是编译执行的,编译器与平台相关,编译生成的可执行文件与平台相关
  • 第二,Java是解释执行的,编译为中间码的编译器与平台无关,编译生成的中间码也与平台无关(一次编译,到处运行),中间码再由解释器解释执行,解释器是与平台相关的,也就是不同的平台需要不同的解释器.

这里再说下语言根据执行方式的不同分类:

  • 第一是编译执行,如上文中说到的C,它把源程序由特定平台的编译器一次性编译为平台相关的机器码,它的优点是执行速度快,缺点是无法跨平台;
  • 第二是解释执行,如HTML,JavaScript,它使用特定的解释器,把代码一行行解释为机器码,类似于同声翻译,它的优点是可以跨平台,缺点是执行速度慢,暴露源程序;
  • 第三种是从Java开始引入的“中间码+虚拟机”的方式,它既整合了编译语言与解释语言的优点,同时如虚拟机又可以解决如垃圾回收,安全性检查等这些传统语言头疼的问题,所以其后微软的.NET平台也使用的这种方式。

3.跨平台的优点

  从上面我们知道了Java跨平台的原理即最后生成的由平台操作的程序文件对于不同的平台是不同的,Java源文件经过编译生成字节码文件.class,字节码文件经由JVM解释生成能被平台执行的机器语言;在这个过程中我们注意字节码文件是相同的,不同的是经过解释后的机器码,Java跨平台正是基于解释.class文件的虚拟机的,但是虚拟机却是不跨平台的,只要在需要运行java应用程序的操作系统上,先安装一个Java虚拟机(JVM JavaVirtual Machine)即可。由JVM来负责Java程序在该系统中的运行。简单来说就是如图所示那样程序代码经过编译之后转换为一种称为Java字节码的中间语言,Java虚拟机(JVM)将对字节码进行解释和运行。编译只进行一次,而解释在每次运行程序时都会进行。编译后的字节码采用一种针对JVM优化过的机器码形式保存,虚拟机将字节码解释为机器码,然后在计算机上面运行。

  同一个.class文件在不同的虚拟机会得到不同的机器指令(Windows和Linux的机器指令不同),但是最终执行的结果却是相同的

  跨平台使得Java的源代码一经编译可以借助于JVM到处运行实现了它的“write once,run anywhere”,但是随着Java在B/S中的广泛使用,跨平台的特性显得就有些鸡肋了,这是因为B/S我们借助浏览器对网络另一端的服务器访问,此时相对应的客户端只是依赖与浏览器,所以平台相对应的只是服务器的平台,所以从客户端来看它的跨平台就很"鸡肋"了,实际上这种想法是很偏见的.下面我们来聊一下Java跨平台的鸡肋.

4.聊聊"鸡肋"的Java跨平台

  我们初学Java的,只怕最深的印象就在于Java的跨平台了,我们的前辈教师,总是会将Java的跨平台夸赞的不得了,可实际接触开发一段时间后,会不会有这么一个疑问呢?那就是Java源自于C++,那C++是如何操作的呢?Java的跨平台究竟在C++的基础上,做出了哪些进步呢?为什么网上有了一种说法,说Java的跨平台很"鸡肋"呢?是这样吗?下边针对这些问题聊聊;

C++语言本来就是跨平台的,不过是“源码级”跨平台。本来就存在针对linux、windows的不同的编译器。所以有C语言“一次编写,到处编译”,Java是“一次编译,到处运行”的说法。如C++创始人酸溜溜的说法,JVM造了一个新的平台,让所有Java程序只能在这个平台上运行,而C和C++的代码可以在几十个不同的平台上运行,从源码这个角度而言,C和C++是跨平台的,而Java不是。这里所说的源码是经过编写未曾编译的。那么这么看起来Java的跨平台是不是真的有些鸡肋了呢?

  这种说法也是有失偏颇的,因为Java和C针对的方向不同所以跨平台承担的责任也就不同了,C主要用于系统底层的开发,如操作系统:Linux,硬件驱动程序。所以对于跨平台就是源码级别的。而Java呢则属于中间码的跨平台。

  C++ 编译生成的是纯二进制的机器指令,而JAVA编译生成的是非纯二进制的字节码。而这种基于Unicode的字节码是不依赖于特定的计算机硬件架构而存在的——这就意味着只要有JVM环境,你的字节码就可以在任何平台上运行。其次,JAVA字节码的二进制数据以固定的格式进行存储和传输,消除了字节顺序的干扰。

  JAVA为什么能跨平台?因为字节码是在虚拟机上运行的,而不是编译器。换而言之,是因为JVM能跨平台安装,所以相应JAVA字节码便可以跟着在任何平台上运行。只要JVM自身的代码能在相应平台上运行,即JVM可行,则JAVA的程序员就可以不用考虑所写的程序要在哪里运行,反正都是在虚拟机上运行,然后变成相应平台的机器语言,而这个转变并不是程序员应该关心的。

Java的起源, 发明的初衷, 最开始Java是为了单片机开发的, 而单片机的发展是很迅速的, 你花了半年为某种单片机开发了程序, 等程序出来了可能这个型号的单片机已经没人用了, Sun当时是为了解决这个问题, 提出了程序只用写一遍编译一遍, 然后让JVM来适应单片机型号的不同.这是最初的跨平台,而发展到了今天呢?我们知道Java已经成为了web开发的主流语言,可是我们开发的时候是在Windows下开发,而部署往往是部署在Linux和Unix下的,所以此时Java的跨平台就又可以大展神威了,因为不管什么时候,Java说白了都是运行在JVM上的,真正需要跨平台的是JVM,所以对于我们编写程序来说,就让编码和跨平台分开了,便利了开发和测试。最为引人注意的一点是,Java在继承C++的优点的时候,也摒弃了C++的缺点,其中有一点就是内存的分配和回收,Java将这部分工作交由JVM自动执行,而减轻了开发人员对于这方面的操作,所以说Java的跨平台是很多因素造成的,发展到了今天Java已经超出了一种语言,更多的成为了一个平台。【想象一下如果是如C++那样的编写方法,那么我们编写后的程序部署后还要再经过编译才可以,而通过Java我们可以在开发中直接编译,只需要将中间码部署在服务器上,其后的事情就不需要我们来管理了,相对来说开发和部署就简单了。】

  我们作为编写端,只注重在编写代码,至于跨平台的任务就交给了JVM来处理,中间码是跨平台的,但JVM却不是跨平台的,这点要注意!

  综上;我们说Java的跨平台鸡肋,是很片面的,针对性不同,没有可比性!

赘述

  我们有没有考虑这么一个问题,那就是同样跨平台,为什么互联网开发更多的选择了Java,而没有选择C呢?

  其实选择哪种语言用于开发,这并没有一个完全正确的答案,我们使用Java开发的程序,同样也是可以使用C开发的,只不过,在互联网发展之初对于语言的要求就是安全,跨平台和支持互联网操作,而Java很好的支持了这些,同时Java源于C++,又摒弃了C++中的不好的东西,所以相对来说Java的简单受到了更多人的推崇,使用的人多了,市场上对其的支持也就多了。

Knowledge Point 20180506 深究Java的跨平台特性的更多相关文章

  1. 关于java的跨平台特性

    Write once, compile anywhere,“一次编译,到处运行”的著名口号大家想必都听说过吧一次编译:把java代码(.java文件)通过编译器转换成字节码(.class文件)(符合j ...

  2. 如何理解JAVA的跨平台特性

    1.java的跨平台,是指java在运行时是凌驾于os之上,是在jvm中运行的,跟os没有直接联系. 2.java跨平台主要是由java的编译方式决定的,因为java是通过jvm先编译再执行,它编译的 ...

  3. java基础二 java的跨平台特性

    一:java跨平台的特性: 1.生成不平台无关系的字节码. 2.通过和平台有关的jvm即java虚拟机来执行字节码.jvm不跨平台. 图示: 疑问:1.为什么我们不直接写字节码? 因为字节码只有jvm ...

  4. Java的跨平台特性

    语言跨平台是编译后的文件跨平台,而不是源程序跨平台.Java源代码首先经过编译器生成字节码,即class文件,该class文件与平台无关,而class文件经过解释执行之后翻译成最终的机器码,这是平台相 ...

  5. IT兄弟连 Java语法教程 Java语言的跨平台特性

    什么是平台 Java是可以跨平台的编程语言,那么首先我们需要知道什么是平台,通常我们把CPU与操作系统的整体称为平台. CPU大家都知道,是计算机的大脑,它既负责思维运算,又负责计算机中各种零部件的命 ...

  6. java发展史与java的语言特性

    概述: Java 体系比较庞杂,功能繁多,这也导致很多人在自学 Java 的时候总是感觉无法建立 全面的知识体系, 无法从整体上把握Java 的原因. 在这里我们先简单了解一下Java 的版本. 具体 ...

  7. 示例解读Java的跨平台原理

    首先简单的解释一下Java跨平台的特征,相当于说写一个Java程序论述上可以运行在不同的操作系统平台上面(此处的平台我们就简单的看成是操作系统平台).下面我们用一些事例来说明它的好处. 我们先了解一些 ...

  8. Java 8新特性解读

    (四)Java 8 相关知识 关于 Java 8 中新知识点,面试官会让你说说 Java 8 你了解多少,下面分享一我收集的 Java 8 新增的知识点的内容,前排申明引用自:Java8新特性及使用 ...

  9. Java 8 新特性:Lambda、Stream和日期处理

    1. Lambda 简介   Lambda表达式(Lambda Expression)是匿名函数,Lambda表达式基于数学中的λ演算得名,对应于其中的Lambda抽象(Lambda Abstract ...

随机推荐

  1. cf1060E. Sergey and Subway(树形dp)

    题意 题目链接 Sol 很套路的题 直接考虑每个边的贡献,最后再把奇数点的贡献算上 #include<bits/stdc++.h> #define Pair pair<int, in ...

  2. BZOJ4568: [Scoi2016]幸运数字(线性基 倍增)

    题意 题目链接 Sol 线性基是可以合并的 倍增维护一下 然后就做完了?? 喵喵喵? // luogu-judger-enable-o2 #include<bits/stdc++.h> # ...

  3. Linux ssh开启服务

    1.登陆linux系统,打开终端命令.输入 rpm -qa |grep ssh 查找当前系统是否已经安装 2.如果没有安装SSH软件包,可以通过yum  或rpm安装包进行安装 启动SSH服务2 安装 ...

  4. SpringMVC中使用DispatcherServlet

    接触Web开发的时候我们会利用Servlet来接收和转发前端页面的各种请求,我们通常会在一个页面中对应一个Servlet来处理这个页面上和用户交互的信息,通常我门遇到5个以内的页面自己来写Servle ...

  5. 毕向东_Java基础视频教程第21天_IO流(1)

    第21天-01-IO流(对象的序列化) ObjectInputStream与ObjectOutputStream 被操作的对象需要实现Serializable接口(标记接口) 非必须, 但强烈建议所有 ...

  6. springIOC学习笔记

    目录 目的 引用 xml方式 配置 配置实例 使用 底层简单模拟 全注解方式 基础 包扫描方式 配置 使用 config方式 配置 使用 spring整合junit 引用 示例 目的 让spring统 ...

  7. leetcode Ch5-Linked List

    一. 1. Remove Duplicates from Sorted List II class Solution { public: ListNode* deleteDuplicates(List ...

  8. java 分次读取大文件的三种方法

    1. java 读取大文件的困难 java 读取文件的一般操作是将文件数据全部读取到内存中,然后再对数据进行操作.例如 Path path = Paths.get("file path&qu ...

  9. Python3网络爬虫:urllib.error异常

    转载请注明作者和出处:http://blog.csdn.net/c406495762/article/details/59488464 一.urllib.error urllib.error可以接收有 ...

  10. Java学习---多线程的学习

    基础知识 每个正在系统上运行的程序都是一个进程(process).每个进程包含一到多个线程(thread).进程也可能是整个程序或者是部分程序的动态执行. 线程是一组指令的集合,或者是程序的特殊段,它 ...