当前位置: 首页 > 图灵资讯 > 技术篇> Java 的可移植性

Java 的可移植性

来源:图灵教育
时间:2024-03-07 09:35:56

  Java™,我一直怀疑最受欢迎的话题,那些自以为是博学的人不断讨论。; 。你可以用一分为二的观点来处理这些问题,最后你被迫相信 Java 带来世界和平,偿还美国国债,或者完全是浪费时间。我经常想参与这些讨论,但直到我能提供广泛的观点,我还是尽量避免谈论它们。

  想象一下,当我从圣诞节回来时,我发现我的下一个任务是学习 Java 当时,我是多么的恐慌(或者应该说是恐惧)。你能说“注意你想要的,因为你可能正在得到它”吗?然而,我很高兴发现学习比我预期的要容易。Java 作为一种长期复杂凌乱的面向对象的设计方法 C++ 世界挣扎的 C 经过多年的面向对象的编程,程序员作为一种回报,我发现他们确实学到了一些原则和技术。的确,我承认我是个人 OLE 热情的人(读过 Nigel Tompson 一系列文章 MSDN 至少在产品代码迁移方面,订阅者会理解我的意思。然而,渐渐地,我离开了无序的行列,至少在考虑 Java 时是这样。

  我的第一个决定是正确的——避免选择类似于“利用你的五天刷牙来学习” Java》这样的书。如果你最近去过书店的计算机技术部分(如果你能出去),你会知道那里有很多 Java 书籍。为了缩小你的搜索范围,你可以选择适合你的书。因为我有丰富的 C 我找到了一些适合程序经验的 C 程序员学习 Java 的书。例如,找到一本Davidid Flanagan 所在的《简单的Java》(Java in a Nutshell 参考专用系统 1996年12月。ISBN:1556592183)。我还买了一本Addison-Wesley 出的《Java (见httpp系列)://www.awl.com/cp/javaseries/),这些书确实很有用,但大部分都是编程参考。根据我通过实践学习的习惯,我很快就熟悉了。我开始写示例 Applet 程序在当时看起来很有用,但很快我意识到我的知识非常有限,需要深入学习。于是我开始浏览微软的Java 开发者 Web 网站和Sun MicroSystems 站点, 并且在下面的网站上找到一些信息(这不是一个全面的列表):

  · Java 开发者 (最好的Java 编程问答)

  · “Java Jolt” (Web Developer.com 指导专栏周刊)

  · “Digital Espresso” (Java 摘要周刊和Mentor Software Solutions 新闻组活动)

  · JavaWorld (关于每月更新的信息 Java 社团的IDG 杂志)

  · Javology (每月更新一次 Java 新闻和在线见解e-zine)

  关于权威人士的一些问题 Java 我的观点鼓舞了我,我回到了原来的起步阶段 Applet 但是视线很快就转移了,开始阅读 Sun Java 开发工具(JDK)的 Applet 示例源程序-httpp://www.javasoft.com/nav/developer/index.html 下载。当然,当我开始阅读实现系统类的源代码时,我觉得阅读示例源程序更有趣。

  我的 Java 实践证明,学习方法相对成功。因为正确的选择适合你 C 编程背景的启蒙书,我对 Java 充分深入的理解。学习的第二阶段通过 Web 浏览网站时,我又掌握了关于网站的知识 Java 开发工具及相关问题的最新信息。阅读源代码后,让我 Java 对结构和实现有本质的认识。

  关于 Java 第一篇系列文章将帮助每一篇文章 C 程序员回答“程序员回答”Java 移植的关键是什么?"这个问题。我将重点介绍设计 Java 在不同的计算机平台之间,应用程序比其他技术具有更好的可移植性。但如果你想彻底理解这一切,Java 良好的内部可移植理论将是你学习的重点。我看到在 Java 新闻组有大量的公告,反映了实际使用中不断出现的真正问题。当然,人们也在抱怨 Java 我将从根本上解释兼容性问题。如果你认为这个主题的文章有帮助,我很感激你能告诉我(我的 e-mail 地址是[emailprotected] )。

  关于可移植性

  创建高可移植性应用程序的便利性在于 Java 设计体系的核心要素。我的大部分编程经验都是关于 C 在20世纪80年代,当我开始我的计算机游戏程序员生涯时,我开始日夜陪伴可移植代码问题。我的游戏公司经常支持几个不同的平台,包括Apple II、C64、Mac、Amiga、Atari ST 和 PC——使用游戏控制台,但未能成功。因此,“移植仪定”似乎成了我的名字。当我在这些平台之间移植游戏时,我学到了一个重要的教训:没有完全可移植的代码;只是可移植代码或多或少的问题。同时,我也掌握了一种方法,可以生成尽可能多的可移植代码。对我们来说,这种方法包括尽可能多的使用 C 语言编写代码,使用我们称之为虚拟机的技术——我们移植到不同平台时使用的基本库代码,作为运行我们的游戏程序所需的虚拟图形和用户输入库。因此,我可以证实我个人创建可移植软件的来之不易的经验 Java 更容易使用可靠性好的技术生成高可移植性的代码。

  总的来说,我认为虚拟机方法平等对待来自某些协议的所有不同平台。为了解释这一点,让我讲一个关于我做的一个项目的故事,这是我退出开发计算机游戏之前的最后一个项目。1988年,我的游戏公司面临着是否放下的艰难决定 Amiga 和Atari ST 对我们 PC 游戏的支持。当时我年轻天真,这个问题激怒了我。既然我们已经在了 Amiga 初步成功——我们怎么能考虑放弃最好的游戏计算机呢?所以我日夜工作了三个月,把我们的虚拟机移植到Amiga 和 Atari ST 在平台上,我相信我可以将这些版本的问题简化为简单的重新编译问题。自然,我成功地实现了我们虚拟机的移植,甚至在不到一周的时间里演示了我们游戏的Amiga 和 Atari ST 版本。你能猜到发生了什么吗?最后,我们放弃了这个平台。在1988年拥有 Amiga 没有人愿意只是为了 PC 移植游戏要花钱。假如他们想要一个 PC,他们会买一个 PC。相反,如果他们想要一台真正的游戏电脑,他们会买一台Amiga(毕竟是1988年)。我从中吸取了一个沉重的教训:虚拟机迫使你在编写软件时尽可能少地使用所需的非公共标准。需要额外的工作来支持不同结构的不同特征,而且不一定总是一个可行的选择。

  一个简短的澄清:我的同事Paul程序员 Johns 在回顾这篇文章时,他指出了我不恰当的修辞隐喻:可移植代码与跨平台代码相同。可移植性意味着简单的重新编译软件可以在另一个平台上运行,而跨平台(Java 辅助建立的定义)意味着代码可以在任何地方运行(或者根据批评者所说的,编译一次可以在任何地方运行)。我觉得Paul 跨平台代码不同于可移植代码,但您可以认为跨平台代码是所有可移植代码的根源。

  是什么使得 Java 适合各种需求,让我们称之为跨平台移植?有三个主要原因:源代码级的可移植性;应用程序编程模型被广泛而准确地描述(特别是作为语言本身的一部分);语言的几个要素使它们易于移植。

  虚拟机

  我已经反复读过Java了 是一种解释性编程语言。但是,这并不严格正确;更准确地说 Java 语言通常(不总是)编译成字节代码,有时(但不总是)被解释。因此, Java 不直接将源代码翻译成特定计算机特有的低级机器指令。但是等一下—当我修理它的时候 Java Applet 在示例程序中,我使用编译器从其源代码中生成一个 Java 类文件。当我使用Microsoft时 Internet 浏览器测试编译的Applet 当我使用Microsoft时s Just-In-Time 加速Java Applet 执行(见 MSDN 库中的“Just-In-Time 对编译器的描述,基础知识文章 Q154580)。

  什么是编译,什么是解释?Java 编译器生成的二进制指令(称为字节代码)由一组全新的虚拟机本身的低级机器指令组成。用于解释已编译的Java 作为创建的软件机器,字节代码的虚拟机本质上可以在任何计算机上运行,甚至可以创建为一个新的硬件平台。它使用Java 作为自己的机器指令,字节代码。换句话说,Java 在Java中,虚拟机可以通过硬件或软件来实现 程序并不“知道”其中的区别。事实上,如果Sun Microsystems JavaStation(一种被称为网络计算机的想法)直接执行Java 字节代码(我不确定),我们可以认为Java 该程序是由软件实现的 Java 虚拟机上的模拟。当然,在一台完全不同的计算机上模拟另一个计算机结构的程序的概念并不新鲜。例如,一些非常喜欢他们旧游戏的人尽最大努力让自己在那里 PC 上继续玩。但Java 语言规格和虚拟机的准确定义是为了使其能够在不同的结构上运行。这就变成了Java 人们对跨平台移植感兴趣的核心因素——它提供了语言和虚拟机规格的准确定义,使虚拟Java能够在任何计算机平台上创建 计算机成为可能。

  这在理论上确实很好,但对本文持怀疑态度的批评者更关心在不同的代码基础和平台上提供相同行为所面临的巨大挑战。事实上,大量相当新的 Java 因此,我们可以开始收集新理论成为实际的成功信息。如果我必须决定是否推荐转向,如果我必须决定的话 Java 利用其跨平台特性,我将仔细研究 Java 实际兼容性优势。(像Ronald Reagan 至少,我会在我计划运行软件的每个地方测试它,并对我发现的问题提出我自己的看法。“吱吱作响的轮子会加油,但不响的轮子会坏掉。”

  如果你读过Q154580的基础知识文章,“Just-In-Time 编译器描述”(MSDN 基础知识库),在虚拟机上执行代码之前,您将看到代码通过 Java 将字节代码编译成不同的本地代码可以改变 Java 运行特点。因此,你可以正常执行解释程序而不是解释程序。这给了你源代码级的移植,让你保留程序的优势,在首选位置为自己的计算机编译高效的代码。

  从自称对可移植性无所不知的人中,我听说了一个正在酝酿的强烈意见:C 语言狂热者声称通过重新编译 C 语言也可以移植,Java 狂热者说,重新编译是移植问题的可悲借口。我塞上耳朵,忽略了这些——一旦你明白了 Java 语言解释的特点(这使得对跨平台的支持达到了源代码级)是 Java 这些说法几乎与可移植性的重要组成部分无关。

  不是另一个 API

  解释性语言本身并不意味着它的程序自然可以具有跨平台的兼容性,因为程序中的所有因素都取决于其下一个操作系统。世界上没有从不同的操作系统中获得这些元素的公共方法(如果你不要求的话) Java 这样做)。因此,软件开发者除了掌握自己首选的编程语言外,还坚持学习不同的应用程序编程界面,或者 API。即使你对 C 熟悉语言的人就像自己的手背一样,需要在各种平台上进行开发 C 应用程序意味着你必须成为各种各样的人 API 的专家。事实上,目标平台上提供的各种目标平台 API 设计可移植程序的关键在于它们之间的区别。Sun 描述一个标准的“Java兼容性”平台,用于定义它们 Java API 解决可移植的复杂问题。但是你知道什么呢?任何支持跨平台的支持 Java API 所有这些概念都非常有效。特定的语言概念和操作系统 API 合并就像说:“如果你打算使用它 C Win322必须用于语言编程® API”。冒着可能受到限制的危险,把语言的概念和 API 组合成一个单一的包确实是创建可移植软件的一大步。瞧!我现在明白了 Java 真正的含义。它不仅仅是一种语言,也是一种语言 API,但是两者的结合!

  将语言和 API 合成一个单一的来源有一个潜在的缺点:如果你不喜欢它 API,或者需要的部分没有发布,或者你发现了很多问题,等等,你就无能为力了。但是,Java API 实际上,它可以扩展 Sun 的 Java 小组正在努力解决两个版本的问题,如过于简单的图形和多媒体支持(见http)://java.sun.com:81/products/api-overview/index.html)。当然,当然,当不能通过对现有的考虑 Java 在实现所需功能时,可以扩展虚拟机顶层类的衍生方法 Java API,同时引入了新的移植问题。如果新的 VM 在所有 Java 在实现这些扩展之前发布兼容平台作为扩展的标准 Java VM 新的内容会导致新的问题。原先下载新 VM 麻烦会刺激人们,尤其是如果他们 VM 当浏览器固有的一部分时,它们将不得不与浏览器一起升级。另一方面,如果是对的 VM 当所有平台都无法实现扩展时,就会出现问题。

  由于 Java 它被解释了,在 Java 中国创建新类库是另一个跨平台的扩展 API 的方法。也就是说,通过使用 Java 你可以以一种完全可移植和兼容的方式扩展语言本身的功能。当然,如果你不能解决关键问题或下层问题 VM 你可能会被限制去做你想做的事。但是你的 Java 可移植程序。事实上,许多公司正在发布具有所有跨平台和扩展功能特征的公司 Java 例如,微软新应用程序的基本类别(AFC)。关于 AFC 更多信息,请参见https://www.tulingxueyuan.cn/d/file/p/20240307/gnkheqf1rf3

  在 JDK 1.0.2 和 1.1 版中,22个 Java 用户界面类描述了一套必须由本地机器操作系统实现的对象。要实现这一点,Java 将这22个特殊类别中的每个类别与一个对等对象联系起来。对等对象负责绘制对象,处理用户输入事件。这22个类别是高级窗口工具包的一部分 Java 和 Java VM 组件的本地代码提供了与平台独特外观和感觉相同的明确定义的交互作用(见 Sun Java “组件结构细节”指南站。对等对象通过本地方法实现其大部分功能。如果是基于Windows® 在机器上,你用调试器跟踪你自己 Java 代码调用到本地方法,并单步执行到本地代码,另一端将出现 Windows 动态链接库(DLL)中。假如你总是像我一样喜欢知道事情是如何工作的,你可以查看微软的。 Java SDK 找微软的网站 Java VM 本地方法是如何工作的(单击左帧”Raw Native Interface”)。我仍然描述了平台的具体外观和感觉部分是如何工作的(以及它是如何改变的),因为我认为这是跨平台移植的关键章节。

  用户界面组件在容器布局中也存在潜在的移植问题(见 Java 由于指南的布局), Java 通过布局管理器系统结构将组件放置到指定位置,允许插入定制管理器。为了保证可移植性,包括其他对象的对象不应过分关注所包含对象的实际位置。否则,屏幕分辨率、容器尺寸、视图属性等无关细节需要在容器代码中处理。通过将 Java 您可以通过连接容器对象和布局管理器对象来解决布局问题。您可以通过定制布局管理器在容器中创建各种视图 Java http指南://www.javasoft.com/nav/read/Tutorial/ui/layout/custom.html)。例如,可以插入自己的布局管理器 AFC 替代 Sun ActiveMovie™的创造性实现方法; 将Listviewew放入Listviewew 容器。所以,如果你关注自己的话 Web 不同屏幕分辨率下页面的外观,或将新组件放入容器中,Java 布局管理器接口可以是解决方案。

  语言移植性更好

  总之,Java 语言本身的元素使其创建跨平台应用程序非常方便。这并不意味着你不能通过其他方式实现可移植性,例如,通过类似的使用 GNU C 如此完美的引用库 C 语言。正如我所说,创建可移植软件主要是一个合适的程序问题。然而,从可移植性的角度来看, Java 语言为此做了很多工作。

  例如,正如我前面提到的,Java 创造者的努力使语言在任何方面都不依赖 Java 由实现来决定。例如,取整形变量的内存尺寸。在 Java short型总是16位,long型总是32位。变量尺寸的严格定义比 C 语言更有限,C 语言中的整形尺寸可以随着结构而增加,但它的比例只能保证 sizeof(short) <= sizeof(int) <= sizeof(long)可移植性更好。类似的,Java 浮点变量的尺寸也是固定的(所有浮点操作都符合一个标准 IEEE 754。参见“计算机系统结构原理”附录 A)。实际上,Java 在语言规范中准确定义了语言规范 ANSI C 留给独立实现的所有基本数据类型的尺寸。

  对数据类型尺寸的概念进行精确定义,Java 固定语言使用专用Unicodede version 2.0 字符集。如果你很高兴在支持不同字符集的平台之间复制一些代码,你会认为固定字符集是多么愤怒。当然,你可以用 Unicode 字符集的 ANSI 代码页面,但你的字符不是8位,所以你看不到任何东西 Java 源的在 #ifdef 多字符集有问题。因此,你不会看到任何东西 #ifdef,因为 Java 没有预处理。Sun 的 Java 小组指出你不需要它,因为 Java 实现等价的方法提供了更好的方法 #条件编译的功能是define语句和条件编译,而条件编译通常用于处理依赖于平台的不同代码的路径选择。到目前为止,我还没有发现这是个问题,但我认为我还没有完全相信。

  在 API 你经常看到的很多东西 Java 语言被直接取代,许多不可移植的跨平台代码 API 元素在 Java 都是可移植的。例如,同步包含在其中。如果你有 Win32 背景,您熟悉同步函数在保护代码中命名部分的功能。在 Java 同步被指定为对象级。这意味着你的应用程序设计满足了一组自然可重复使用对象的同步需求。当然,没有理由不让你建立特殊的东西 Java 类,就像“干脆” Win32 该类用于代码中临界区的用法。

  线程是常见的 API 在另一个领域中看到,但已经直接建立起来 Java 语言中。在 Java 确定您的线程模型与从自己的应用程序中提取的任务或对象密切相关。和同步一样,Java 在对象级锁定中建立串行化,Java 将您的线程活动放在一个对象级别。符合我的传统观念,我会 Java 的功能与 Win32 对比功能,发现 Java 的不足。例如,用等待函数同步对象(在 Java 这是实现多线程执行同步的唯一途径),这只是 Win32 其中一种控制线程模式。Java 只提供单个对象的调度方法,不能在多个阻塞对象中指定要调度的线程 Win32 提供多对象的调度和预警等待函数(在 MSDN 库中的 SDK 在平台中搜索“”Wait Functions”)。假如你在处理 Java 限制,你最好确保你的程序不会与未来有关 Java 版本冲突。

  当今软件最大的可用性问题之一不是粗糙的用户界面设计。但问题比那简单得多——软件的小缺点。Java 采用实用的方法解决普遍而不可预测的程序错误;选择的异常被用作整个语言的一部分 JDK 在类实现中抛出适当的异常,迫使开发者考虑如何处理他们的程序失败。在编译过程中,选定的异常允许编译器检查是否有代码来处理执行函数时可能出现的问题。换句话说,除非你正确处理错误,否则你不会通过编译检查单独操作。多好的概念啊!但是什么时候是你最后一次为无法解释的软件错误而痛苦呢?根据我的经验,在编写每行代码之前,创建一个强大的软件需要专业的协调努力。我非常感激 Java 提供的额外标准确保了这种努力。当然,一些 C++ 编译器(包括微软)有异常检查,但这个特性不能与之相匹配 API 集成标准语言元素。编译过程中的错误检查为语言的概念和优势提供了另一种 API 合并的例子。(在 Web 上面,我遇到了这样一篇文章“一篇一篇” C++ 将通信软件转换为 Java 框架体验”如果你对此感兴趣,可以去看看)

  你真的关心可移植软件吗?

  当我自学 Java 时创建的 Applet 这是一个可以在多个平台上运行的程序,不需要任何“额外”的工作(当然,除了测试,还有一些小问题需要我纠正)。另外一方面,我已经和很多关心可以在任何地方运行的软件开发人员进行了讨论,但是他们还没有被他们说服。毕竟,Windows 和 MS-DOS® 占据我们时代的统治地位。但核心平台的观点却被忽略了 Web 只有内容才是核心事实,无论是现在还是将来,你都需要每个人都能访问你的内容。

  即使你不在乎移植,其他人也会这样做。例如,在企业中,所有大型机器、服务器、台式机器、便携式和手持式之间的自动兼容性可以大大降低编程量和技术支持。当然,Web 各种出版物都可以到达 Unix 工作站和 Windows CE 手持式 PCs。

  我曾经有一些想法 Java 被遗忘的技术被过度宣传和很快成为失败的人讨论过。其他人相信 Java 对未来如此暗淡的评价,是生活在过去的人们的自嘲。我认为事实可能是两者之间的结果:Java 它是一种工具,就像其它工具一样,只有正确使用才能体现其价值。