作 为 一 种 编 程 语 言,JAVA 提 供 了 一 种 最 简 单 同 时 也 是 人 们 最 熟 悉 的 可 移 植 性-- 源 代 码 移 植。 这 意 味 着 任 意 一 个JAVA 程 序, 不 论 它 运 行 在 何 种CPU、 操 作 系 统 或JAVA 编 译 器 上, 都 将 产 生 同 样 的 结 果。 这 并 不 是 一 个 新 的 概 念。 人 们 使 用C、C++ 也 可 以 产 生 同 样 的 效 果。 但 是 使 用C 或C++ 编 程 人 们 可 以 有 太 多 的 选 择, 在 许 多 细 节 上 它 都 没 有 严 格 定 义, 如: 未 初 始 化 变 量 的 值、 对 已 释 放 的 内 存 的 存 取、 浮 点 运 算 的 尾 数 值 等 等。 所 以 除 非 你 一 开 始 就 严 格 按 照 系 统 无 关 的 概 念 来 进 行 设 计, 否 则 这 种 可 移 植 性 只 能 是 一 种 理 论 上 的 设 想 而 不 能 形 成 实 践。 总 之, 尽 管C 和C++ 有 严 密 的 语 法 定 义, 它 们 的 语 意(symantics) 定 义 还 不 是 标 准 的。 这 种 语 意 上 的 不 统 一 使 得 同 一 段 程 序 在 不 同 的 系 统 环 境 下 会 产 生 不 同 的 结 果。 有 时 即 使 系 统 情 况 完 全 相 同 而 仅 仅 由 于 编 译 器 的 设 置 不 同 也 会 产 生 令 人 意 想 不 到 的 结 果。 而JAVA 就 不 同 了。 它 定 义 了 严 密 的 语 意 结 构, 而 使 编 译 器 不 承 担 这 方 面 的 工 作。 另 外,JAVA 对 程 序 的 行 为 的 定 义 也 比C 和C++ 严 格, 如: 它 提 供 了 内 存 自 动 回 收 功 能(Garbage Collection), 使 程 序 不 能 访 问 越 界 内 存; 它 对 未 初 始 化 的 变 量 提 供 确 定 值 等 等。 它 的 这 些 特 性 能 够 减 小 在 不 同 平 台 上 运 行 的JAVA 程 序 之 间 的 差 异, 也 使 得JAVA 具 有 即 使 没 有JAVA 虚 拟 机 的 存 在 的 情 况 下 比C 和C++ 更 好 的 平 台 无 关 性。 然 而, 这 些 特 点 也 有 它 不 利 的 一 面。JAVA 设 想 运 行 于 具 有32 位 字 节 长 度 且 每 字 节 为8 位 的 计 算 机 上, 这 就 使 得 那 些8 位 字 长 的 计 算 机 和 一 些 巨 型 机 不 能 有 效 的 运 行JAVA 程 序。 在 这 样 的 平 台 上 就 只 能 运 行 那 些 可 移 植 的C 和C++ 程 序 了。
大 多 数 编 译 器 产 生 的 目 标 代 码 只 能 运 行 在 一 种CPU 上( 如Intel 的x86 系 列), 即 使 那 些 能 支 持 多 种CPU 的 编 译 器 也 不 能 同 时 产 生 适 合 多 种CPU 的 目 标 代 码。 如 果 你 需 要 在 三 种CPU( 如x86、SPARC 和MIPS) 上 运 行 同 一 程 序, 就 必 须 编 译 三 次。
但JAVA 编 译 器 就 不 同 了。JAVA 编 译 器 产 生 的 目 标 代 码(J-Code) 是 针 对 一 种 并 不 存 在 的CPU--JAVA 虚 拟 机(JAVA Virtual Machine), 而 不 是 某 一 实 际 的CPU。JAVA 虚 拟 机 能 掩 盖 不 同CPU 之 间 的 差 别, 使J-Code 能 运 行 于 任 何 具 有JAVA 虚 拟 机 的 机 器 上。
虚 拟 机 的 概 念 并 不 是JAVA 所 特 有 的: 加 州 大 学 几 年 前 就 提 出 了PASCAL 虚 拟 机 的 概 念; 广 泛 用 于Unix 服 务 器 的Perl 脚 本 也 是 产 生 与 机 器 无 关 的 中 间 代 码 用 于 执 行。 但 针 对 Internet 应 用 而 设 计 的JAVA 虚 拟 机 的 特 别 之 处 在 于 它 能 产 生 安 全 的 不 受 病 毒 威 胁 的 目 标 代 码。 正 是 由 于Internet 对 安 全 特 性 的 特 别 要 求 才 使 得JVM 能 够 迅 速 被 人 们 接 受。 当 今 主 流 的 操 作 系 统 如OS/2、MacOS、Windows95/NT 都 已 经 或 很 快 提 供 对J-Code 的 支 持。
作 为 一 种 虚 拟 的CPU,JAVA 虚 拟 机 对 于 源 代 码(Source Code) 来 说 是 独 立 的。 我 们 不 仅 可 以 用JAVA 语 言 来 生 成J-Code, 也 可 以 用Ada95 来 生 成。 事 实 上, 已 经 有 了 针 对 若 干 种 源 代 码 的J-Code 编 译 器, 包 括Basic、Lisp 和Forth。 源 代 码 一 经 转 换 成J-Code 以 后, JAVA 虚 拟 机 就 能 够 执 行 而 不 区 分 它 是 由 哪 种 源 代 码 生 成 的。 这 样 做 的 结 果 就 是CPU 可 移 植 性。
将 源 程 序 编 译 为J-Code 的 好 处 在 于 可 运 行 于 各 种 机 器 上, 而 缺 点 是 它 不 如 本 机 代 码 运 行 的 速 度 快。
即 使 经 过 重 新 编 译, 大 多 数 的 用C 和C++ 编 写 的Windows 程 序 也 不 能 在Unix 或Macintosh 系 统 上 运 行。 这 是 为 什 么 呢 ? 因 为 程 序 员 在 编 写Windows 程 序 时 使 用 了 大 量 的WindowsAPI 和 中 断 调 用, 而Windows 程 序 对 系 统 功 能 的 调 用 与Unix 和Macintosh 程 序 有 很 大 的 差 别, 所 以 除 非 将 全 套Windows API 移 植 到 其 它 操 作 系 统 上, 否 则 重 编 译 的 程 序 仍 不 能 运 行。
JAVA 采 用 了 提 供 一 套 与 平 台 无 关 的 库 函 数( 包 括AWT、UTIL、LANG 等 等) 的 方 法 来 解 决 这 个 问 题。 就 象JVM 提 供 了 一 个 虚 拟 的CPU 一 样,JAVA 库 函 数 提 供 了 一 个 虚 拟 的GUI 环 境。JAVA 程 序 仅 对JAVA 库 函 数 提 出 调 用, 而 库 函 数 对 操 作 系 统 功 能 的 调 用 由 各 不 同 的 虚 拟 机 来 完 成。JAVA 也 在 它 的OS/GUI 库 中 使 用 了 一 种“ 罕 见 名 称 符”(least-commom-denominator) 来 提 供 对 某 种 特 定 操 作 系 统 的 功 能 调 用, 即 此 功 能 只 在 特 定 环 境 下 生 效 而 在 其 它 操 作 系 统 下 则 被 忽 略。 这 样 做 的 好 处 在 于 可 以 针 对 某 操 作 系 统 生 成 拥 有 人 们 熟 悉 的 界 面 的 应 用 程 序 而 同 时 此 程 序 又 能 在 其 它 系 统 下 运 行。 缺 点 则 是 系 统 中 的 某 些 功 能 调 用 有 很 强 的 依 赖 性 因 而 在JAVA 的 虚 拟OS/API 中 难 以 实 现。 遇 到 这 种 情 况, 程 序 员 就 只 能 写 不 可 移 植 的 程 序 了。
总 之,JAVA 在 可 移 植 性 方 面 的 特 点 使 它 在Internet 上 具 有 广 泛 的 应 用 前 景。 同 时 它 本 身 具 有 的 防 病 毒 的 能 力 也 使 它 在 需 要 高 可 靠 性 的 应 用 中 占 有 一 席 之 地