摘自:http://bbs.51cto.com/thread-944897-1.html

 

相信学习android的人都会想过或者想知道这个问题,那就请你耐心的看完这篇文章吧,你会对android与java的关系有个深一点的理解。

Android是否相当于Java?请注意,我并没有说相等,我说的是相当,就像P = NP里的那样。

相当的类/字节码格式      在很多层面上,Android和Java都有明显的相当。Android应用程序是用Java(TM)语言写成的,使用JDK的javac(或等效工具,例如ECJ)来编译。这个过程产生标准的Java字节码(.class文件)。这些文件再转化成Android的.dex文件,从使用的角度来看,它就是一种不同格式的Java class文件。不错,这是一种更优秀的格式;对Sun自从1994年以来的设计有了很大的改进。但就如你可以把一个GIF格式的图片转换成更高级的完美的完全等效的PNG格式,尽管它们的字节流完全的不同。

      等效的文件格式在细节的实现上非常的不同,主要是为了优化。就好比,如果我们简单的满足于低效率的视频数据流,没有采用高端的、跨不同框架的压缩技术,那我们就可以避免跟MPEGLA视频解码专利做斗争的麻烦了。
Android特异的classfile设计有好几种动机;而为了避免和Sun的知识产权保护冲突显然是一个主要的因素。不管怎样,Google并没有走的离Java足够远。两种文件格式非常的类似。它们在特定的底层数据结构上有区别,但这些结构体在语法上一致的,存储完全相同的信息。我相信在JavaSE或JavaME VM里可以轻易的在它们的系统classloader里添加一个.dex分析器来加载”Android classes”。

Android SDK 依赖于.java -> .class -> .dex 转换的事实情况既微不足道也毫无损失。“毫无损失”的事实很重要:当GIF = PNG 时,跟受损的JPG文件就不等了 —— 它解码不出完全相同的信息。如果JVM和Dalvik都各自独立,你很难写出一个相对简单的工具将一种编译过的代码转换成另一种 —— 而且不做任何妥协:不丢失信息,不使用冗余来补偿某种特征在一种VM中是first-class而在另一种中却不是的情况,不需要额外的runtime层 上在一种VM中实现另一种VM的核心API。

(我知道dx转换器有多么的复杂。我看过它的源代码。那个字节码转换器是一个巨大的,全功能的反编译/重编译器,通 过SSA构造完成。但是这个转换器在概念上仍然是无足轻重的;从Java字节码到Dalvik字节码的映射在设计上是很平滑的。堆栈相对于寄存器架构中细 节上进行了优化;而重要的东西,例如VM层的类型系统是完全一致的。)

VM相当      这Dalvik 和 JVM 的相当也是很容易看清楚的。并不只是源代码或字节码格式上的问题:它们的runtime对等物上也一样。一但一个”Android class”被加载到Dalvik VM里,它就会像Java class一样运行,像Java class一样工作。 如果你懂得Java编程(深入到高级的,底层的细节),你也就懂得Android编程。你只需要学一些新的API和框架概念。他们是对等的系统。

      是否记得微软的.NET? 当.NET刚出世时,Java阵营迅速的反击指责.NET是对Java的剽窃。我也是其中的一份子,但今天我看问题更清楚了。是的,它过去是个严重的剽窃产品;C# 1.0 就是一个… 区分一种语言和另一种语言最简单的方法就是看它们的惯用风格 —— 例如toString() 相对于 ToString()。 但在最重要的VM规范里,微软做了很大的功课。它的CLR,CLI,和核心框架,都非常的不同于Java,所以我们不能说JVM = CLR这个等式。你不可能使用一个简单的文件格式转换工具把你编译好的Java class转换成能在.NET runtime上运行的代码。

要证据吗?你只需看一看IKVM就知道了。这是一个非常有趣的项目,它能够使Java和.NET跨平台兼容,于是,你的Java代码可以在不做修改的情况下在CLR(或者是等效的.NET runtime,比如Mono)上运行… 但IKVM并不是一个简单的、类dx的 文件格式转换器。对Java class的转化、对Java核心API的适配,都是十分的复杂,即使对一个简单的HelloWorld程序也是这样。各个平台的内部机制,如反射,安 全,并行,异常处理,字节码验证,I/O,以及其它核心API,特征上大致相同,但是在细节上完全不同,一些死胡同的情况会迫使IKVM不得不钻越一个又 一个的火圈来让Java代码运行到了.NET VM上。它需要依赖于一个巨大的额外的runtime层,来适配从OpenJDK源代码里来的完整JavaSE API。我大致的关注IKVM的开发已经有数年了 —— 我阅读这精彩的IKVM 博客 – 所以我完全清楚他们为了让Java程序和JavaSE应用适配到.NET上所做的巨大的努力。(这项工作仍然没有完工;而且很多部分都需要以丧失某些性能为代价。)

(老的Visual J++ Visual J# 也不是一个简单的 Java-to-.NET 转换器。我不想讨论它,但我们完全可以说Visual J# 对Java的兼容并不比最早期的IKVM强多少。)

      我把P = NP引进来了讨论;有些人把图灵等效(Turing-equivalence)理论引进来,说任何图灵完备的平台/语言/VM都是相互等价的。这也没错, 但与本论题无关。图灵模型这种方式太泛化了;使用这种表面价值来考量会把更个软件专利系统摧毁(尽管这不是个坏事!)。我们需要在地上为JVM等效画条 线,一条更接近实用需求而远离图灵等效的线。按我的观点,这微不足道的二进制格式转换,穷尽的高层源代码和runtime的兼容,使Android明显的 处于Java等效的这条线内。

APIs 和 Runtime 相当       Android使用了一个相当大的JavaSE APIs子集。这些APIs (来自于Harmony项目)都是全新的实现,但它们是以JavaSE为模子。如果不是因为TCK许可证问题,Harmony完全可以取得JavaSE认 证。但这并没有改变这样的一个事实:Harmony 和 JavaSE APIs是 完全的等效的 —— 这是特意的,不是偶然的。就像Charles Nutter——有名的JRuby人物——最近写道:

Android支持一个不完整的(但相当大的)Java 1.5 类库子集。这个子集大到一个复杂的JRuby项目几乎不经任何修改就能在Android上运行,很少有限制情况。

    

看起来Dalvik对JVM是如此的接近,它不得不完全兼容大部分的JVM规范,包括完全详细的JMM (就像Android支持Java风格的线程和并发,已经深入到了高级的java.util.concurrent包里了)。可为什么有如此多的”Dalvik是个新VM“或”Dalvik不能运行Java类“的说法呢(90%的讨论这场诉讼的论坛和博客都持这种观点)。

最后的思考     这篇博客并不是关于Oracle和Google诉讼官司的法律依据的。我将会忽略(我会删除掉)那些跑题的评论(跟Android = Java不相关的话)。我只是讨厌那些”Android跟Java完全没关系“的胡说八道;Google和 Android的拥护者必须要找一个更有意义的论据。

(我将拭目以待这场官司的进展,带着我所有的预见,直到所有细节和最终结果都出来。除非你有内部消息(我没有),不要太天真。 保持冷静。 我们并不知道Oracle的 —— 或 Google的 —— 真正的全部动机和计划。我们并不知道这荧幕背后的故事,自从2007年Google首次宣告Android的诞生(这导致了JavaME生态环境的崩 溃), Sun就痛恨不已,但最后还是不得不夹着尾巴行事。我不相信任何一个有10亿美金的股东控股公司会有利他主义的动机:Google不会,Oracle不 会,即使我喜爱的老的Sun公司也不会。我们等着看吧。)

我不相信Google没有能力创造出一种既不背离Java太远,又以Java风格为基础的平台(就像.NET做的那样)。 Dalvik,以及Android框架,它们可能是在权衡了与大量的现有的Java程序,类库,Java天才,和Java工具链高度兼容的愿望的最后结 果。微软在一咬牙一跺脚后放弃了现成移植Java带来的好处,创造了全新的.NET。Google没有这样做。

这个Android = Java等式显然并不是包括所有的东西(不是一一对应的)。每种平台都有自己一些独特的API,当然,Android是一个完整的操作系统,包括一个 Linux-based的内核,图形系统和电信堆栈,等等。很显然,我只是谈论其中最常用的部分:Java为中心的用户使用区/依赖于Java源代码、 Java classes(切不管什么格式)、Java APIs(包括成千上万的常用JavaSE APIs)和出色的类Java的虚拟机的应用框架。对于Android和其它的Java平台之间的关系有个准确的说法,就是使用版本的概念。我曾记得有个 博客说过这样的话”Android里没有’J’“。那么,我现在说也不晚:我建议把Android改名为Java GE(Java Google Edition)。这样一来就再也不会导致混淆了

android与java的关系的更多相关文章

  1. Android版本信息及与Linux和Java的关系

    1.Android与Linux和Java的关系 Android严格来说,不能算是Linux,Android是一个统称,具体来说,是Google用了Linux的一个核心,用这个核心来管理进程,控制硬件. ...

  2. [转载] 深入理解Android之Java虚拟机Dalvik

    本文转载自: http://blog.csdn.net/innost/article/details/50377905 一.背景 这个选题很大,但并不是一开始就有这么高大上的追求.最初之时,只是源于对 ...

  3. Android(或者Java)通过HttpUrlConnection向SpringMVC请求数据(数据绑定)

    问题描写叙述 当我们使用SpringMVC作为服务端的框架时,有时不仅仅要应对web前端(jsp.javascript.Jquery等)的訪问请求,有时还可能须要响应Android和JavaSE(桌面 ...

  4. 深入理解Android之Java虚拟机Dalvik

    一.背景 这个选题非常大,但并非一開始就有这么高大上的追求. 最初之时,仅仅是源于对Xposed的好奇.Xposed差点儿是定制ROM的神器软件技术架构或者说方法了. 它究竟是怎么实现呢?我本意就是想 ...

  5. 线程、进程概念与Android系统组件的关系

    Android系统是Google公司基于Linux内核开发的开源手机操作系统.通过利用 Linux 内核的优势,Android 系统使用了大量操作系统服务,包括进程管理.内存管理.网络堆栈.驱动程序. ...

  6. Android(java)学习笔记267:Android线程池形态

    1. 线程池简介  多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力.     假设一个服务器完成一项任务所需时间为:T1 创建线程时间, ...

  7. Android中Java反射技术的使用示例

    import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Metho ...

  8. Android service binder aidl 关系

    /********************************************************************************** * Android servic ...

  9. Android(java)学习笔记207:开源项目使用之gif view

    1. 由于android没有自带的gif动画,我在Android(java)学习笔记198:Android下的帧动画(Drawable Animation) 播客中提到可以使用AnimationVie ...

随机推荐

  1. 2015 acm taipei L-Reward the Troop(uvalive 7465)(找规律)

    原题链接 就大概说的是一个将军要给部下发勋章,他的部下以和别人不一样的勋章为荣,但是他没这么多钱,所以问你最少要多少钱 要求是每个人的上司是他的上两级,他的下两级是他的部下,每个人的勋章不能和他的上司 ...

  2. [bzoj3371][poj2009][Usaco2004 Mar]Moo University - Emergency Pizza Order 定制比萨饼

    标题这么长的..真是让感觉人头大脚轻. 贴题面先. Description     Moo大学的餐厅必须为$C(1\leq C\leq 1000)$头入学的奶牛新生定制比萨饼.比萨饼可以在比萨小屋订做 ...

  3. eclipse包名分层级显示

    eclipse包名像文件列表那样显示设置方法

  4. Servlet过滤器---编码转换过滤器

    该实例用于将请求与相应的编码设置为当前网站的默认编码 java类: import java.io.IOException; import javax.servlet.Filter; import ja ...

  5. OpenCV学习笔记(十一) 轮廓操作

    在图像中寻找轮廓 首先利用Canny算子检测图像的边缘,再利用Canny算子的输出作为 寻找轮廓函数 findContours 的输入.最后用函数 drawContours 画出轮廓.边界Counto ...

  6. 做出一个SwitchButton的效果,并详细学习一下onDraw(Canvas canvas)方法的使用

    代码的灵感和原理主要来自于android自定义开关控件-SlideSwitch http://blog.csdn.net/singwhatiwanna/article/details/9254309这 ...

  7. 使用pip命令报You are using pip version 9.0.3, however version 18.0 is available pip版本过期.解决方案

    使用pip命令安装或卸载第三方库时报You are using pip version 9.0.3, however version 18.0 is available.错误,一般情况下是pip版本过 ...

  8. 孤荷凌寒自学python第三十九天python 的线程锁Lock

    孤荷凌寒自学python第三十九天python的线程锁Lock (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 当多个线程同时操作一个文件等需要同时操作某一对象的情况发生时,很有可能发生冲突, ...

  9. 洛谷P1071潜伏者(提高组)

    题目描述 R国和S国正陷入战火之中,双方都互派间谍,潜入对方内部,伺机行动.历尽艰险后,潜伏于S国的R 国间谍小C终于摸清了 S 国军用密码的编码规则: 1. S国军方内部欲发送的原信息经过加密后在网 ...

  10. 仅需几行代码 轻松实现ETH代币空投

    仅需几行代码 轻松实现ETH代币空投 批量发送以太坊,部署下面的合约,然后往下面的合约打币,就可以分发 ragma solidity ^0.4.21; contract batchTransfer { ...