2006 年 12 月 SUN 公 司 发 布 JDK6.0 目 前 主 流 的 JDK 是 Sun 公 司 发 布 的 JDK, 除 了 Sun 之 外, 还 有 很 多 公 司 和 组 织 都 开 发 了 自 己 的 JDK, 例 如 IBM 公 司 开 发 的 JDK,BEA 公 司 的 Jr

Size: px
Start display at page:

Download "2006 年 12 月 SUN 公 司 发 布 JDK6.0 目 前 主 流 的 JDK 是 Sun 公 司 发 布 的 JDK, 除 了 Sun 之 外, 还 有 很 多 公 司 和 组 织 都 开 发 了 自 己 的 JDK, 例 如 IBM 公 司 开 发 的 JDK,BEA 公 司 的 Jr"

Transcription

1 1 Java 入 门 Java 是 一 门 很 优 秀 的 编 程 语 言, 具 有 面 向 对 象 与 平 台 无 关 安 全 稳 定 和 多 线 程 等 特 点, 是 目 前 软 件 设 计 中 极 为 健 壮 的 编 程 语 言 Java 不 仅 可 以 用 来 开 发 大 型 的 应 用 程 序, 而 且 特 别 适 合 于 Internet 的 应 用 开 发 Java 确 实 具 备 了 一 次 编 写, 处 处 运 行 的 特 点,Java 已 成 为 网 络 时 代 最 重 要 的 编 程 语 言 之 一 1.1 Java 的 诞 生 在 1990 年,Sun 公 司 成 立 了 一 个 由 James Gosling 领 导 的 软 件 设 计 团 队, 他 们 合 作 的 项 目 称 为 绿 色 计 划 他 们 认 为 计 算 机 技 术 发 展 的 一 个 趋 势 是 数 字 家 电 之 间 的 通 讯 James 开 始 负 责 为 设 备 和 用 户 之 间 的 交 流 创 建 一 种 能 够 实 现 网 络 交 互 的 语 言 随 着 大 量 的 时 间 和 金 钱 投 入 到 绿 色 计 划, 他 们 创 建 了 一 种 语 言 这 种 语 言 一 开 始 被 叫 做 Oak, 这 个 名 字 得 自 于 Gosling 想 名 字 时 看 到 了 窗 外 的 一 棵 橡 树, 后 来 被 改 为 了 Java Java 的 快 速 发 展 得 利 于 Internet 和 Web 的 出 现, 到 了 2000 年,Java 已 经 成 为 世 界 上 最 流 行 的 电 脑 语 言 绿 色 小 组 当 初 设 计 Java 是 为 了 面 向 数 字 家 庭, 支 持 各 种 家 电 设 备 他 们 没 有 想 到 的 是,Java 支 持 的 计 算 模 式, 实 际 上 就 是 互 联 网 的 模 式 Java 的 重 要 历 史 事 件 : 时 间 事 件 1995 年 5 月 23 日 Java 语 言 诞 生 1996 年 1 月 第 一 个 JDK-JDK1.0 诞 生 1996 年 4 月 10 个 最 重 要 的 操 作 系 统 供 应 商 申 明 将 在 其 产 品 中 嵌 入 JAVA 技 术 1997 年 2 月 18 日 JDK1.1 发 布 1998 年 12 月 8 日 JAVA2 企 业 平 台 J2EE 发 布 1999 年 6 月 SUM 公 司 发 布 Java 的 三 个 版 本 : 标 准 版 (J2SE) 企 业 版 (J2EE) 和 微 型 版 (J2ME) 2004 年 9 月 30 日 J2SE1.5 发 布, 成 为 Java 语 言 发 展 史 上 的 又 一 里 程 碑 为 了 表 示 该 版 本 的 重 要 性,J2SE1.5 更 名 为 Java SE 5.0 第 1 页

2 2006 年 12 月 SUN 公 司 发 布 JDK6.0 目 前 主 流 的 JDK 是 Sun 公 司 发 布 的 JDK, 除 了 Sun 之 外, 还 有 很 多 公 司 和 组 织 都 开 发 了 自 己 的 JDK, 例 如 IBM 公 司 开 发 的 JDK,BEA 公 司 的 Jrocket, 还 有 GNU 组 织 开 发 的 JDK 等 等 印 度 尼 西 亚 有 一 个 重 要 的 盛 产 咖 啡 的 岛 屿, 中 文 名 叫 爪 哇, 开 发 人 员 为 这 种 新 的 语 言 起 名 为 Java, 其 寓 意 是 为 世 人 端 上 一 杯 香 浓 的 热 咖 啡 现 在 就 让 我 们 来 一 起 品 尝 吧 1.2 Java 编 程 语 言 是 什 么 Java 的 内 容 很 丰 富, 实 现 的 功 能 也 很 多, 我 们 从 以 下 几 个 角 度 来 描 述 它 一 种 计 算 机 编 程 语 言 一 种 软 件 开 发 平 台 一 种 软 件 运 行 平 台 一 种 软 件 部 署 环 境 句 法 与 C++ 相 似, 语 义 与 Small Talk 相 似 用 来 开 发 applets, 又 用 来 开 发 applications 1 Java 是 一 种 计 算 机 编 程 语 言 语 言 我 们 说 的 普 通 话 英 语 都 是 语 言, 语 言 是 一 种 交 流 的 工 具, 语 言 具 有 创 造 性 和 结 构 性, 并 且 代 表 一 定 的 意 义 比 如 我 说 下 课 了, 大 家 都 明 白 什 么 意 思, 证 明 这 个 语 句 的 意 思 表 达 清 楚 了, 正 规 的 语 言 在 交 流 上 是 不 能 有 歧 义 的 计 算 机 编 程 计 算 机 编 程 就 是 : 把 程 序 员 的 要 求 和 设 想, 按 照 能 够 让 计 算 机 看 得 懂 的 规 则 和 约 定, 编 写 出 来 的 过 程, 就 是 编 程 编 程 的 结 果 就 是 一 些 计 算 机 能 够 看 懂 并 能 够 执 行 和 处 理 的 东 西, 我 们 把 它 叫 做 软 件 或 者 程 序 事 实 上, 程 序 就 是 我 们 对 计 算 机 发 出 的 命 令 集 ( 指 令 集 ) Java 是 一 种 计 算 机 编 程 语 言 首 先,Java 是 一 种 语 言, 也 就 是 Java 是 用 来 交 流 的, 那 么 用 来 谁 和 谁 交 流 呢? 很 明 显 就 是 程 序 员 和 计 算 机 交 流, 换 句 话 说 把 我 们 的 要 求 和 设 想 用 Java 语 言 表 达 出 来, 那 么 计 算 机 能 看 懂, 就 能 够 按 照 我 们 要 求 运 行, 而 这 个 过 程 就 是 我 们 所 说 的 使 用 Java 编 程, 所 以 我 们 讲 Java 是 一 种 计 算 机 编 程 语 言 为 了 让 计 算 机 看 懂,Java 会 有 一 系 列 的 规 则 和 约 定, 这 些 就 是 Java 的 语 法 2 Java 是 一 种 软 件 开 发 平 台 什 么 是 软 件 开 发 可 以 简 单 地 理 解 为 : 编 程 的 结 果 是 软 件 或 者 程 序, 而 编 程 的 过 程 就 是 软 件 开 发 软 件 开 发 的 基 本 步 骤 包 括 : 需 求 分 析 概 要 设 计 详 细 设 计 编 码 测 试 维 护 等 阶 段 需 求 分 析 : 这 里 指 的 需 求 不 仅 仅 是 用 户 需 求, 应 该 是 开 发 中 遇 到 的 所 有 的 需 求 比 如, 你 首 第 2 页

3 先 要 知 道 做 这 个 项 目 是 为 了 解 决 什 么 问 题 ; 测 试 案 例 中 应 该 输 入 什 么 数 据 为 了 清 楚 地 知 道 这 些 需 求, 你 经 常 要 和 客 户 项 目 经 理 以 及 项 目 伙 伴 调 查 研 究, 这 就 是 需 求 分 析 概 要 设 计 详 细 设 计 : 根 据 软 件 系 统 需 求 完 成 对 系 统 的 设 计, 确 定 强 壮 的 系 统 架 构, 设 计 模 块 层 次 用 户 界 面 和 数 据 库 表 结 构 编 码 : 开 发 代 码, 完 成 设 计 的 具 体 实 现 测 试 : 利 用 测 试 工 具 按 照 测 试 方 案 和 业 务 流 程 对 产 品 进 行 功 能 和 性 能 测 试, 对 测 试 方 案 可 能 出 现 的 问 题 进 行 分 析 和 评 估, 并 修 改 代 码 维 护 : 根 据 用 户 需 求 的 变 化 或 硬 件 环 境 的 变 化, 对 应 用 程 序 进 行 部 分 或 全 部 的 修 改 用 以 下 的 流 程 图 来 表 达 这 个 过 程 : 需 求 分 析 概 要 设 计 软 件 设 计 和 实 现 软 件 测 试 详 细 设 计 编 单 码 元 测 试 代 码 测 试 交 付 维 护 功 能 测 试 验 收 测 试 什 么 是 开 发 平 台 在 软 件 开 发 的 过 程 中, 我 们 需 要 很 多 的 工 具 来 辅 助 我 们 的 工 作, 不 可 能 什 么 都 从 头 自 己 做 我 们 把 编 程 的 环 境 和 相 应 的 辅 助 工 具 统 称 为 开 发 环 境, 开 发 平 台 就 是 用 来 提 供 这 个 开 发 环 境 的 车 床 工 人 需 要 一 个 车 床 才 能 工 作 一 样 Java 是 一 种 开 发 平 台 Java 不 单 纯 是 一 个 编 程 的 语 言, 它 自 身 提 供 了 一 系 列 开 发 Java 所 需 要 的 环 境 和 工 具, 来 进 行 编 译 解 释 文 档 生 成 打 包 等, 比 如 :javac.exe java.exe 等 等, 这 些 我 们 后 面 会 讲 到, 所 以 我 们 讲 Java 是 一 个 开 发 平 台 3 Java 是 一 种 软 件 运 行 平 台 什 么 是 软 件 的 运 行 平 台 如 同 人 类 需 要 阳 光 空 气 水 和 食 物 才 能 正 常 存 活 一 样, 软 件 最 终 要 能 够 运 行, 也 需 要 一 系 列 的 外 部 环 境, 来 为 软 件 的 运 行 提 供 支 持, 而 提 供 这 些 支 持 的 就 是 运 行 平 台 Java 是 一 种 软 件 运 行 平 台 第 3 页

4 Java 本 身 提 供 Java 软 件 所 需 要 的 运 行 环 境,Java 应 用 可 运 行 在 安 装 了 JRE(Java Runtime Environment) 的 机 器 上, 所 以 我 们 说 Java 是 一 个 运 行 平 台 JRE:Java Runtime Environment,Java 运 行 环 境 4 Java 是 一 种 软 件 部 署 环 境 什 么 是 软 件 的 部 署 简 单 地 讲, 部 署 就 是 安 装, 就 是 把 软 件 放 置 到 相 应 的 地 方, 并 且 进 行 相 应 的 配 置 ( 一 般 称 作 部 署 描 述 ) 让 软 件 能 够 正 常 运 行 起 来 Java 是 一 种 软 件 部 署 环 境 Java 本 身 是 一 个 开 发 的 平 台, 开 发 后 的 Java 程 序 也 是 运 行 在 Java 平 台 上 的 也 就 是 说, 开 发 后 的 Java 程 序 也 是 部 署 在 Java 平 台 上 的, 这 个 尤 其 在 后 面 学 习 JEE(Java 的 企 业 版 ) 的 时 候, 体 现 更 为 明 显 1.3 Java 能 干 什 么 Java 能 做 的 事 情 很 多, 涉 及 到 编 程 领 域 的 各 个 方 面 桌 面 级 应 用 : 尤 其 是 需 要 跨 平 台 的 桌 面 级 应 用 程 序 桌 面 级 应 用 : 简 单 的 说 就 是 主 要 功 能 都 在 我 们 本 机 上 运 行 的 程 序, 比 如 word excel 等 运 行 在 本 机 上 的 应 用 就 属 于 桌 面 应 用 企 业 级 应 用 企 业 级 应 用 : 简 单 的 说 就 是 大 规 模 的 应 用, 一 般 使 用 人 数 较 多, 数 据 量 较 大, 对 系 统 的 稳 定 性 安 全 性 可 扩 展 性 和 可 装 配 性 等 都 有 比 较 高 的 要 求 举 例 说 明 一 下 : 组 件 化 : 企 业 级 应 用 通 常 比 较 复 杂, 组 件 化 能 够 更 好 对 业 务 进 行 建 模, 提 高 系 统 的 扩 展 性 和 维 护 性, 做 到 组 件 复 用 分 布 式 : 企 业 组 织 机 构 复 杂, 同 一 地 有 多 个 分 部, 或 者 跨 省, 甚 至 跨 国, COABA, RMI, Web Services 是 JavaEE 中 支 持 的 分 布 式 访 问 技 术, 还 有 分 布 式 的 连 接, 如 系 统 需 要 接 入 多 个 数 据 源, 可 以 用 JNDI 来 透 明 实 现 事 务 管 理 : 为 了 保 证 数 据 的 安 全 操 作 安 全 访 问, 事 务 是 不 可 缺 少 的, 事 实 上 只 要 操 作 数 据 库, 就 离 不 开 事 务 管 理 消 息 管 理 : 通 过 消 息 来 实 现 异 步 触 发 从 而 降 低 系 统 耦 合 性, 提 高 系 统 吞 吐 量 一 个 电 子 商 务 网 站 也 可 以 使 用 消 息 来 进 行 异 步 发 邮 件, 但 在 企 业 级 应 用 当 中, 根 据 实 际 需 求 还 可 以 演 变 成 更 多 复 杂 的 应 用,JEE 提 供 JMS 实 现 消 息 管 理 安 全 性 : 企 业 级 应 用 的 数 据 都 更 为 敏 感 ( 比 如 公 司 的 销 售 数 据 财 务 数 据 ), 需 要 为 此 提 供 严 格 的 安 全 性 保 护, 企 业 级 组 织 的 复 杂 性 接 入 访 问 的 多 样 性 增 加 了 安 全 策 略 实 施 的 难 度, JAAS 为 此 提 供 了 一 整 套 的 安 全 策 略, 方 便 企 业 级 应 用 以 安 全 一 致 便 捷 的 方 式 实 现 安 全 机 第 4 页

5 制 目 前 企 业 级 应 用 是 Java 应 用 最 广 泛 的 一 个 领 域, 几 乎 一 枝 独 秀 包 括 各 种 行 业 应 用 企 业 信 息 化 电 子 政 务 等, 包 括 办 公 自 动 化 OA, 人 力 资 源 HR, 客 户 关 系 管 理 CRM, 企 业 资 源 计 划 ERP 供 应 链 管 理 SCM 企 业 设 备 管 理 系 统 EAM 产 品 生 命 周 期 管 理 PLM 面 向 服 务 体 系 架 构 SOA 商 业 智 能 BI 项 目 管 理 PM 营 销 管 理 流 程 管 理 WorkFlow 财 务 管 理 等 等 几 乎 所 有 你 能 想 到 的 应 用 嵌 入 式 设 备 及 消 费 类 电 子 设 备 包 括 无 线 手 持 设 备 智 能 卡 通 信 终 端 医 疗 设 备 信 息 家 电 ( 如 数 字 机 顶 盒 电 冰 箱 ) 汽 车 导 航 系 统 等 都 是 近 年 以 来 热 门 的 Java 应 用 领 域, 尤 其 是 手 机 上 的 Java 应 用 程 序 和 Java 游 戏, 更 是 普 及 嵌 入 式 装 置 答 题 上 区 分 为 两 种 : 一 种 是 运 算 功 能 有 限 电 力 供 应 也 有 限 的 嵌 入 式 装 置, 例 如 : PDA 手 机 ; 另 外 一 种 则 是 运 算 能 力 相 对 较 佳 并 且 电 力 供 应 上 相 对 比 较 充 足 的 嵌 入 式 装 置, 比 如 : 冷 气 机 电 冰 箱 电 视 机 顶 盒 除 了 上 面 提 到 的,Java 还 有 很 多 功 能 : 如 进 行 数 学 运 算 显 示 图 形 界 面 进 行 网 络 操 作 进 行 数 据 库 操 作 进 行 文 件 的 操 作 等 等 1.4 Java 有 什 么 Java 体 系 比 较 庞 杂, 功 能 繁 多, 这 也 导 致 很 多 人 在 自 学 Java 的 时 候 总 是 感 觉 无 法 建 立 全 面 的 知 识 体 系, 无 法 从 整 体 上 把 握 Java 的 原 因 在 这 里 我 们 先 简 单 了 解 一 下 Java 的 版 本 Java 分 成 三 种 版 本, 分 别 是 : Java 标 准 版 (JSE) Java 微 缩 版 (JME) 和 Java 企 业 版 (JEE) 每 一 种 版 本 都 有 自 己 的 功 能 和 应 用 方 向 Java 标 准 版 : JSE(Java Standard Edition) JSE 是 Sun 公 司 针 对 桌 面 开 发 以 及 低 端 商 务 计 算 解 决 方 案 而 开 发 的 版 本, 例 如 : 我 们 平 常 熟 悉 的 Application 桌 面 应 用 程 序 这 个 版 本 是 个 基 础, 它 也 是 我 们 平 常 开 发 和 使 用 最 多 的 技 术,Java 的 主 要 的 技 术 将 在 这 个 版 本 中 体 现 本 书 主 要 讲 的 就 是 JSE Java 微 缩 版 :JME(Java Micro Edition) JME 是 对 标 准 版 JSE 进 行 功 能 缩 减 后 的 版 本, 于 1999 年 6 月 由 Sun Microsystems 第 一 次 推 向 Java 团 体 它 是 一 项 能 更 好 满 足 Java 开 发 人 员 不 同 需 求 的 广 泛 倡 议 的 一 部 分 Sun Microsystems 将 JME 定 义 为 一 种 以 广 泛 的 消 费 性 产 品 为 目 标 的 高 度 优 化 的 Java 运 行 时 环 境, 应 用 范 围 包 括 掌 上 电 脑 移 动 电 话 可 视 电 话 数 字 机 顶 盒 和 汽 车 导 航 系 统 及 其 他 无 线 设 备 等 JME 是 致 力 于 消 费 产 品 和 嵌 入 式 设 备 的 开 发 人 员 的 最 佳 选 择 尽 管 早 期 人 们 对 它 看 好 而 且 Java 开 发 人 员 团 体 中 的 热 衷 人 士 也 不 少, 然 而 JME 最 近 才 开 始 从 其 影 响 更 大 的 同 属 产 品 JEE 和 第 5 页

6 JSE 的 阴 影 中 走 出 其 不 成 熟 期 JME 在 开 发 面 向 内 存 有 限 的 移 动 终 端 ( 例 如 掌 上 电 脑 移 动 电 话 ) 的 应 用 时, 显 得 尤 其 实 用 因 为 它 是 建 立 在 操 作 系 统 之 上 的, 使 得 应 用 的 开 发 无 须 考 虑 太 多 特 殊 的 硬 件 配 置 类 型 或 操 作 系 统 因 此, 开 发 商 也 无 须 为 不 同 的 终 端 建 立 特 殊 的 应 用, 制 造 商 也 只 需 要 简 单 地 使 它 们 的 操 作 平 台 可 以 支 持 JME 便 可 Java 企 业 版 :JEE(Java Enterprise Edition) JEE 是 一 种 利 用 Java 平 台 来 简 化 企 业 解 决 方 案 的 开 发 部 署 和 管 理 相 关 的 复 杂 问 题 的 体 系 结 构 JEE 技 术 的 基 础 就 是 核 心 Java 平 台 或 Java 平 台 的 标 准 版,JEE 不 仅 巩 固 了 标 准 版 中 的 许 多 优 点, 例 如 一 次 编 写 处 处 运 行 的 特 性 方 便 存 取 数 据 库 的 JDBC API CORBA 技 术 以 及 能 够 在 Internet 应 用 中 保 护 数 据 的 安 全 模 式 等 等, 同 时 还 提 供 了 对 EJB(Enterprise Java Beans) Java Servlets API JSP(Java Server Pages) 以 及 XML 技 术 的 全 面 支 持 其 最 终 目 的 就 是 成 为 一 个 能 够 使 企 业 开 发 者 大 幅 缩 短 投 放 市 场 时 间 的 体 系 结 构 JEE 体 系 结 构 提 供 中 间 层 集 成 框 架 来 满 足 无 需 太 多 费 用 而 又 需 要 高 可 用 性 高 可 靠 性 以 及 可 扩 展 性 的 应 用 的 需 求 通 过 提 供 统 一 的 开 发 平 台,JEE 降 低 了 开 发 多 层 应 用 的 费 用 和 复 杂 性, 同 时 提 供 对 现 有 应 用 程 序 集 成 强 有 力 支 持, 完 全 支 持 Enterprise Java Beans, 有 良 好 的 向 导 支 持 打 包 和 部 署 应 用, 添 加 了 目 录 支 持, 增 强 了 安 全 机 制, 提 高 了 性 能 JEE 是 对 标 准 版 进 行 功 能 扩 展, 提 供 一 系 列 功 能, 用 来 解 决 进 行 企 业 应 用 开 发 中 所 面 临 的 复 杂 的 问 题 具 体 的 我 们 会 放 到 后 面 JEE 的 课 程 去 讲 三 个 版 本 之 间 的 关 系 : JEE 几 乎 完 全 包 含 JSE 的 功 能, 然 后 在 JSE 的 基 础 上 添 加 了 很 多 新 的 功 能 JME 主 要 是 JSE 的 部 分 功 能 子 集, 然 后 再 加 上 一 部 分 额 外 添 加 的 功 能 如 下 图 所 示 : JEE JSE JME Java 的 API 类 库 之 中 有 一 组 所 谓 的 核 心 类 (CoreClass, 即 java.*), 在 核 心 类 之 外 还 有 所 谓 的 扩 充 类 (Extended Class, 即 javax.*) 根 据 对 这 两 种 类 的 支 持 程 度, 进 而 区 分 出 几 种 不 同 的 Java 版 本 我 们 必 须 以 Java Standard Edition(JSE) 作 为 基 准, 这 个 版 本 做 了 所 有 Java 标 准 规 格 之 中 所 定 义 的 核 心 类, 也 支 持 所 有 的 Java 基 本 类 JSE 定 位 在 客 户 端 程 序 的 应 用 上 第 6 页

7 从 JSE 往 外 延 伸, 其 外 面 为 Java Enterprise Edition(JEE), 此 版 本 除 了 支 持 所 有 的 标 准 核 心 类 外, 而 且 还 增 加 了 许 多 支 持 企 业 内 部 使 用 的 扩 充 类, 支 持 Servlet/ JSP 的 javax.servlet.* 类 支 持 Enterprise Java Bean 的 javax.ejb.* 类 当 然,JEE 必 定 支 持 所 有 的 Java 基 本 类 JEE 定 位 在 服 务 器 端 (server-side) 程 序 的 应 用 上 从 JSE 向 内 看, 是 Java Micro Edition(JME), 它 所 支 持 的 只 有 核 心 类 的 子 集 合, 在 JME CLDC 的 规 格 之 中, 只 支 持 java.lang.* java.io.* 以 及 java.util.* 这 些 类 此 版 本 也 增 加 了 一 些 支 持 微 小 装 置 的 扩 充 类, 如 javax.microedition.io.* 类 然 而, 此 版 本 并 不 支 持 所 有 的 Java 基 本 类, 就 标 准 的 JMECLDC, 也 就 是 能 在 PalmOS 上 执 行 的 KVM(KVirtualMachine) 来 说, 它 就 不 支 持 属 于 浮 点 数 (float double) 的 Java 基 本 类 JME 定 位 在 嵌 入 式 系 统 的 应 用 上 最 里 层, 还 有 一 个 Java 的 Smart Card 版 本, 原 本 在 Java 的 文 件 之 中 并 没 有 这 样 定 义, 但 是 将 它 画 在 JME 内 部 是 很 合 理 的 因 为 SmartCard 版 本 只 支 持 java.lang.* 这 个 核 心 类, 比 起 JME 所 支 持 的 核 心 类 更 少, 但 它 也 有 属 于 自 己 的 扩 充 类, 如 javacard.* javacardx.* 这 些 类 SmartCard 版 本 只 支 持 Boolean 与 Byte 这 两 种 Java 基 本 类, 此 版 本 定 位 在 SmartCard 的 应 用 上 1.5 Java 的 特 点 简 单 地 说,Java 具 有 如 下 特 点 : 简 单 的 面 向 对 象 的 平 台 无 关 的 多 线 程 的 安 全 的 高 效 的 健 壮 的 动 态 的 等 特 点 简 单 的 简 单 是 指 Java 既 易 学 又 好 用 不 要 将 简 单 误 解 为 这 门 编 程 语 言 很 干 瘪 你 可 能 很 赞 同 这 样 的 观 点 : 英 语 要 比 阿 拉 伯 语 言 容 易 学 但 这 并 不 意 味 着 英 语 就 不 能 表 达 丰 富 的 内 容 和 深 刻 的 思 想, 许 多 荣 获 诺 贝 尔 文 学 奖 的 作 品 都 是 用 英 文 写 的 如 果 你 学 习 过 C++, 你 会 感 觉 Java 很 眼 熟, 因 为 Java 中 许 多 基 本 语 句 的 语 法 和 C++ 一 样, 像 常 用 的 循 环 语 句 控 制 语 句 等 和 C++ 几 乎 一 样, 但 不 要 误 解 为 Java 是 C++ 的 增 强 版,Java 和 C++ 是 两 种 完 全 不 同 的 编 程 语 言, 它 们 各 有 各 的 优 势, 将 会 长 期 并 存 下 去,Java 和 C++ 已 成 为 软 件 开 发 者 应 当 掌 握 的 编 程 语 言 如 果 从 语 言 的 简 单 性 方 面 看,Java 要 比 C++ 简 单,C++ 中 有 许 多 容 易 混 淆 的 概 念, 或 者 被 Java 弃 之 不 用 了, 或 者 以 一 种 更 清 楚 更 容 易 理 解 的 方 式 实 现, 例 如,Java 不 再 有 指 针 的 概 念 面 向 对 象 的 面 向 对 象 是 指 以 对 象 为 基 本 粒 度, 其 下 包 含 属 性 和 方 法 对 象 的 说 明 用 属 性 表 达, 而 通 过 使 用 方 法 来 操 作 这 个 对 象 面 向 对 象 技 术 使 得 应 用 程 序 的 开 发 变 得 简 单 易 用, 节 省 代 码 基 于 对 象 的 编 程 更 符 合 人 的 思 维 模 式, 使 人 们 更 容 易 编 写 程 序 Java 是 一 种 面 向 对 象 的 语 言, 也 继 承 了 面 向 对 象 的 诸 多 好 处, 如 代 码 扩 展 代 码 复 用 等 我 们 将 在 以 后 的 章 节 中 详 细 地 讨 论 类 对 象 等 概 念 平 台 无 关 的 与 平 台 无 关 是 Java 最 大 的 优 势 其 他 语 言 编 写 的 程 序 面 临 的 一 个 主 要 问 题 是 : 操 作 系 统 的 变 化, 处 理 器 升 级 以 及 核 心 系 统 资 源 的 变 化, 都 可 能 导 致 程 序 出 现 错 误 或 无 法 运 行 而 用 Java 写 的 程 序 不 用 修 改 就 可 在 不 同 的 软 硬 件 平 台 上 运 行 这 样 就 能 实 现 同 样 的 程 序 既 可 以 在 第 7 页

8 Windows 下 运 行, 到 了 Unix 或 者 Linux 环 境 不 用 修 改 就 直 接 可 以 运 行 了 Java 主 要 靠 Java 虚 拟 机 (JVM) 实 现 平 台 无 关 性 平 台 无 关 性 就 是 一 次 编 写, 到 处 运 行 :Write Once, Run Anywhere 多 线 程 的 Java 实 现 了 内 置 对 多 线 程 的 支 持 多 线 程 允 许 同 时 完 成 多 个 任 务 实 际 上 多 线 程 使 人 产 生 多 个 任 务 在 同 时 执 行 的 错 觉, 因 为, 目 前 的 计 算 机 的 处 理 器 在 同 一 时 刻 只 能 执 行 一 个 线 程, 但 处 理 器 可 以 在 不 同 的 线 程 之 间 快 速 地 切 换, 由 于 处 理 器 速 度 非 常 快, 远 远 超 过 了 人 接 收 信 息 的 速 度, 所 以 给 人 的 感 觉 好 像 多 个 任 务 在 同 时 执 行 C++ 没 有 内 置 的 多 线 程 机 制, 因 此 必 须 调 用 操 作 系 统 的 多 线 程 功 能 来 进 行 多 线 程 程 序 的 设 计 安 全 的 安 全 性 可 以 分 为 四 个 层 面, 即 编 译 类 装 载 字 节 码 校 验 沙 箱 机 制 高 效 的 高 级 语 言 程 序 必 须 转 换 为 机 器 语 言 程 序 才 能 执 行, 但 不 同 的 计 算 机 系 统 所 使 用 的 机 器 语 言 不 同 Java 为 了 实 现 一 次 编 译, 随 处 运 行 的 目 标,Java 的 源 程 序 在 编 译 时, 并 不 直 接 编 译 成 特 定 的 机 器 语 言 程 序, 而 是 编 译 成 与 系 统 无 关 的 字 节 码, 由 Java 虚 拟 机 (JVM ) 来 执 行 当 JVM 解 释 执 行 Java 程 序 时,Java 实 时 编 译 器 (Just-In-Time,JIT) 会 将 字 节 码 译 成 目 标 平 台 对 应 的 机 器 语 言 的 指 令 代 码 早 先 的 许 多 尝 试 解 决 跨 平 台 的 方 案 对 性 能 要 求 都 很 高 其 他 解 释 执 行 的 语 言 系 统, 如 BASIC PERL 都 有 无 法 克 服 的 性 能 缺 陷 然 而,Java 却 可 以 在 非 常 低 档 的 CPU 上 顺 畅 运 行, 这 是 因 为 Java 字 节 码 是 经 过 精 心 设 计 的, 能 够 直 接 使 用 JIT 编 译 技 术 将 字 节 码 转 换 成 高 性 能 的 本 机 代 码 事 实 上,Java 的 运 行 速 度 随 着 JIT 编 译 器 技 术 的 发 展 已 接 近 于 C++ 健 壮 的 Java 是 健 壮 的 语 言 为 了 更 好 地 理 解 Java 的 健 壮 性, 先 讨 论 一 下 在 传 统 编 程 环 境 下 程 序 设 计 失 败 的 主 要 原 因 : 内 存 管 理 错 误 和 误 操 作 引 起 的 异 常 或 运 行 时 异 常 在 传 统 的 编 程 环 境 下, 内 存 管 理 是 一 项 困 难 乏 味 的 工 作 例 如, 在 C 或 C++ 中, 必 须 手 工 分 配 释 放 所 有 的 动 态 内 存 如 果 忘 记 释 放 原 来 分 配 的 内 存, 或 是 释 放 了 其 他 程 序 正 在 使 用 的 内 存 时, 就 会 出 错 在 传 统 的 编 程 环 境 下, 异 常 情 况 可 能 经 常 由 被 零 除 Null 指 针 操 作 文 件 未 找 到 等 原 因 引 起, 必 须 用 既 繁 琐 又 难 理 解 的 一 大 堆 指 令 来 进 行 管 理 对 此,Java 通 过 自 行 管 理 内 存 分 配 和 释 放, 从 根 本 上 消 除 了 有 关 内 存 的 问 题 Java 提 供 垃 圾 收 集 器, 可 自 动 收 集 闲 置 对 象 占 用 的 内 存 通 过 提 供 面 向 对 象 的 异 常 处 理 机 制 来 解 决 异 常 处 理 的 问 题 通 过 类 型 检 查 Null 指 针 检 测 数 组 边 界 检 测 等 方 法, 在 开 发 早 期 发 现 程 序 错 误 动 态 的 Java 语 言 具 有 动 态 特 性 Java 动 态 特 性 是 其 面 向 对 象 设 计 方 法 的 扩 展, 允 许 程 序 动 态 地 装 入 运 行 过 程 中 所 需 的 类, 这 是 C++ 进 行 面 向 对 象 程 序 设 计 所 无 法 实 现 的 C++ 程 序 设 计 过 程 中, 每 当 在 类 中 增 加 一 个 实 例 变 量 或 一 种 成 员 函 数 后, 引 用 该 类 的 所 有 子 类 都 必 须 重 新 编 译, 否 则 将 导 致 程 序 崩 溃 第 8 页

9 1.6 构 建 Java 开 发 环 境 我 们 先 来 学 习 构 建 Java 开 发 环 境, 让 大 家 对 Java 有 更 实 际 的 了 解 下 面 以 JDK6.0 在 Windows XP 上 的 安 装 配 置 为 例 来 讲 述 : 第 一 步 : 下 载 JDK 从 SUN 网 站 下 载 JDK6 或 以 上 版 本, 地 址 是 downloads/index.jsp, 这 里 以 jdk-6u10-rc2-bin-b32-windows-i586-p-12_sep _2008.exe 版 为 例, 如 下 图 : 第 二 步 : 安 装 JDK (1) 双 击 jdk-6u10-rc2-bin-b32-windows-i586-p-12_sep_2008.exe 文 件, 出 现 如 下 安 装 界 面 : 第 9 页

10 (2) 然 后 出 现 下 面 的 界 面 (3) 点 击 接 受 按 钮, 然 后 出 现 下 列 界 面 (4) 点 击 界 面 上 的 更 改 按 钮, 可 以 设 置 需 要 安 装 到 的 路 径, 然 后 点 击 下 一 步, 会 进 行 JDK 的 安 装, 请 耐 心 等 待 第 10 页

11 (5) 直 到 出 现 JRE 的 安 装, 如 下 图 : (6) 可 以 选 择 更 改, 然 后 在 弹 出 的 界 面 选 择 安 装 JRE 的 路 径, 然 后 点 击 确 定 也 可 以 不 更 改 安 装 路 径, 点 击 下 一 步, 出 现 下 面 的 界 面 这 里 介 绍 了 Java 语 言 开 发 的 一 个 Office 软 件, 和 微 软 的 Office 各 有 千 秋, 因 为 是 Java 开 发 的, 大 家 可 以 支 持 一 下, 最 主 要 的 它 是 免 费 的 第 11 页

12 (7) 直 到 出 现 如 下 界 面, 表 示 安 装 完 成 : (8) 不 想 查 看 产 品 注 册 信 息 的 话, 就 直 接 点 击 完 成 按 钮, 安 装 JDK 就 完 成 了 第 12 页

13 (9) 安 装 完 成 过 后,JDK 文 件 夹 如 下 图 : C:\Program Files\Java\jdk1.6.0_10: 是 JDK 的 安 装 路 径 bin: 是 binary 的 简 写, 存 放 的 是 Java 的 各 种 可 执 行 文 件, 常 用 的 命 令 有 编 译 器 javac.exe 解 释 器 java.exe 现 的 include: 需 要 引 入 的 一 些 头 文 件, 主 要 是 c 和 c++ 的,JDK 本 身 是 通 过 C 和 C++ 实 jre:java 运 行 环 境 lib: 是 library 的 简 写,JDK 所 需 要 的 一 些 资 源 文 件 和 资 源 包 C:\Program Files\Sun\JavaDB :JDK6 新 加 入 的 Apache 的 Derby 数 据 库, 支 持 JDBC4.0 的 规 范 第 三 步 : 配 置 环 境 变 量 安 装 完 成 后, 还 要 进 行 Java 环 境 的 配 置, 才 能 正 常 使 用, 步 骤 如 下 : (1) 在 我 的 电 脑 点 击 右 键 选 择 属 性, 如 下 图 所 示 : 第 13 页

14 (2) 在 弹 出 界 面 上 : 选 择 高 级 环 境 变 量, 如 下 图 所 示 : (3) 弹 出 如 下 界 面, 我 们 的 设 置 就 在 这 个 界 面 上 : 第 14 页

15 (4) 点 击 环 境 变 量 界 面 的 系 统 变 量 栏 的 新 建 按 钮, 弹 出 界 面 如 下 图 : 在 上 面 填 写 变 量 名 为 : JAVA_HOME, 变 量 值 为 : C:\Program Files\Java\jdk1.6.0_10, 如 下 图 所 示 : 点 击 确 定 按 钮 第 15 页

16 (5) 再 次 点 击 环 境 变 量 界 面 的 系 统 变 量 栏 的 新 建 按 钮 在 弹 出 的 窗 口 中 填 写 变 量 名 为 : classpath, 变 量 值 为 :.;, 注 意 是 点 和 分 号, 如 下 图 所 示 : 点 击 确 定 按 钮 (6) 如 下 图 所 示 : 在 系 统 变 量 里 面 找 到 Path 这 一 项, 然 后 双 击 它, 在 弹 出 的 界 面 上, 在 变 量 值 开 头 添 加 如 下 语 句 %JAVA_HOME%\bin;, 注 意 不 要 忘 了 后 面 的 分 号, 如 下 图 所 示 : 然 后 点 击 编 辑 系 统 变 量 界 面 的 确 定 按 钮 第 16 页

17 (7) 点 击 环 境 变 量 界 面 的 确 定 按 钮 (8) 点 击 系 统 属 性 界 面 的 确 定 按 钮 Java 开 发 环 境 的 设 置 就 完 成 了 那 么 为 何 要 设 置 这 些 环 境 变 量 呢? JAVA_HOME: 配 置 到 JDK 安 装 路 径 注 意 : 变 量 名 必 须 书 写 正 确, 全 部 大 写, 中 间 用 下 划 线 有 以 下 好 处 : 为 了 方 便 引 用 比 如,JDK 安 装 在 C:\Program Files\Java\jdk1.6.0_10 目 录 里, 则 设 置 JAVA_HOME 为 该 目 录 路 径, 那 么 以 后 要 使 用 这 个 路 径 的 时 候, 只 需 输 入 %JAVA_HOME% 即 可, 避 免 每 次 引 用 都 输 入 很 长 的 路 径 串 归 一 原 则 当 JDK 路 径 被 迫 改 变 的 时 候, 仅 需 更 改 JAVA_HOME 的 变 量 值 即 可, 否 则, 你 就 要 更 改 任 何 用 绝 对 路 径 引 用 JDK 目 录 的 文 档, 要 是 万 一 你 没 有 改 全, 某 个 程 序 找 不 到 JDK, 后 果 是 可 想 而 知 为 第 三 方 软 件 服 务 基 于 Java 的 第 三 方 软 件 会 引 用 约 定 好 的 JAVA_HOME 变 量, 那 么 它 们 能 够 找 到 JDK 的 位 置, 不 然, 将 不 能 正 常 使 用 该 软 件 如 果 某 个 软 件 不 能 正 常 使 用, 不 妨 想 想 是 不 是 这 个 问 题 PATH: 提 供 给 操 作 系 统 寻 找 到 Java 命 令 工 具 的 路 径 通 常 是 配 置 到 JDK 安 装 路 径 \bin 完 成 配 置 以 后, 使 用 编 译 器 和 解 释 器 就 会 很 方 便, 可 以 在 任 何 路 径 下 使 用 bin 目 录 下 的 Java 命 令, 而 不 需 要 写 出 完 整 的 路 径 :C:\Program Files\Java\jdk1.6.0_10 \bin\java CLASSPATH: 提 供 程 序 在 运 行 期 寻 找 所 需 资 源 的 路 径, 比 如 :.class 类 文 件 文 件 图 片 等 等 在 windows 环 境 下 配 置. 代 表 当 前 路 径, 那 么 在 执 行 java 命 令 时, 就 会 先 到 当 前 路 径 寻 找 class 类 文 件 这 个 配 置 对 于 Java 初 学 者 比 较 难 理 解, 我 们 在 后 面 的 Java 运 行 过 程 中, 再 详 细 体 会 的 配 置 注 意 : 在 windows 操 作 系 统 上, 最 好 在 CLASSPATH 的 配 置 里 面, 始 终 在 前 面 保 持.; 通 过 在 windows 窗 口 设 置 环 境 变 量, 可 以 永 久 更 改 系 统 环 境 变 量 也 可 以 在 dos 命 令 行 窗 口, 通 过 dos 命 令 的 方 式 修 改 环 境 变 量, 具 体 命 令 如 下 : set JAVA_HOME=C:\Program Files\Java\jdk1.6.0_10; set path=%java_home%\bin; set classpath=.; 但 通 过 这 种 方 式 修 改 的 环 境 变 量 只 在 当 前 的 dos 命 令 行 窗 口 有 效, 对 于 其 他 的 dos 命 令 行 窗 口 则 无 效 第 17 页

18 1.6.4 第 四 步 : 检 测 安 装 配 置 是 否 成 功 进 行 完 上 面 的 步 骤, 基 本 的 安 装 和 配 置 就 好 了, 怎 么 知 道 安 装 成 功 没 有 呢? (1) 点 击 开 始 点 击 运 行, 在 弹 出 的 对 话 框 中 输 入 cmd, 如 下 图 示 : (2) 然 后 点 击 确 定, 在 弹 出 的 dos 命 令 行 窗 口 里 面, 输 入 javac, 然 后 回 车, 出 现 如 下 界 面 则 表 示 安 装 配 置 成 功 现 在 Java 的 开 发 环 境 就 配 置 好 了, 如 果 出 现 下 面 的 提 示, 说 明 刚 才 的 环 境 变 量 的 配 置 有 问 题, 需 要 从 头 一 步 一 步 检 查 第 18 页

19 注 意 : 如 果 更 改 了 系 统 环 境 变 量 的 配 置, 必 须 重 新 打 开 dos 窗 口, 就 是 打 开 一 个 新 的 dos 窗 口, 环 境 变 量 的 新 配 置 才 会 有 效, 否 则,dos 窗 口 就 还 应 用 旧 的 环 境 变 量 的 旧 配 置 有 些 人 已 经 跃 跃 欲 试 的 想 要 马 上 开 始 学 习 如 何 编 写 Java 程 序 了, 下 面 先 来 体 会 第 一 个 Java 程 序 1.7 一 个 基 本 的 Java 应 用 程 序 HelloWorld 像 其 它 编 程 语 言 一 样,Java 编 程 语 言 也 被 用 来 创 建 应 用 程 序 一 个 共 同 的 应 用 程 序 范 例 是 在 屏 幕 上 显 示 字 串 Hello World! 下 列 代 码 给 出 了 这 个 Java 应 用 程 序 如 果 是 第 一 次 看 到 Java 代 码, 可 能 都 不 明 白 每 一 个 代 码 的 意 义, 没 有 关 系, 主 要 是 来 体 会 一 下 Java 程 序 是 什 么 样 子, 在 脑 海 里 有 个 印 象, 然 后 可 以 先 模 仿 着 做 HelloWorld 1.// 这 里 是 注 释 2.// HelloWorld 应 用 示 例 3.// 4.public class HelloWorld{ 5. public static void main (String args[]){ 6. System.out.println(" 你 好, 欢 迎 来 到 Java 快 车!"); 以 上 程 序 行 是 在 dos 窗 口 上 打 印 你 好, 欢 迎 来 到 Java 快 车! 所 需 的 最 少 组 件 描 述 HelloWorld 1.// 这 里 是 注 释 2.// HelloWorld 应 用 示 例 3.// 程 序 中 的 1-3 行 是 注 释 行 第 19 页

20 4. public class HelloWorld{ 第 4 行 声 明 类 名 为 HelloWorld 类 名 (ClassName) 是 在 源 文 件 中 指 明 的, 它 可 在 与 源 代 码 相 同 的 目 录 上 创 建 一 个 ClassName.class 文 件 在 本 例 题 中, 编 译 器 创 建 了 一 个 称 为 HelloWorld.class 的 文 件, 它 包 含 了 公 共 类 HelloWorld 的 编 译 代 码 5. public static void main (String args[]){ 第 5 行 是 程 序 执 行 的 起 始 点 ( 入 口 ) Java 解 释 器 必 须 发 现 这 一 严 格 定 义 的 点, 否 则 将 拒 绝 运 行 程 序 其 它 程 序 语 言 ( 特 别 是 C 和 C++) 也 采 用 main() 声 明 作 为 程 序 执 行 的 起 始 点 此 声 明 的 不 同 部 分 将 在 本 课 程 的 后 几 部 分 介 绍 如 果 在 程 序 的 命 令 行 中 给 出 了 任 何 自 变 量 ( 命 令 行 参 数 ), 它 们 将 被 传 递 给 main() 方 法 中 被 称 作 args 的 String 数 组 在 本 例 题 中, 未 使 用 自 变 量 public 说 明 方 法 main() 可 被 任 何 程 序 访 问, 包 括 Java 解 释 器 static 是 一 个 告 知 编 译 器 main() 是 用 于 类 HelloWorldApp 中 的 方 法 的 关 键 字 为 使 main() 在 程 序 做 其 它 事 之 前 就 开 始 运 行, 这 一 关 键 字 是 必 要 的 void 表 明 main() 不 返 回 任 何 信 息 这 一 点 是 重 要 的, 因 为 Java 编 程 语 言 要 进 行 谨 慎 的 类 型 检 查, 包 括 检 查 调 用 的 方 法 确 实 返 回 了 这 些 方 法 所 声 明 的 类 型 String args[] 是 一 个 字 符 串 类 型 的 数 组 声 明, 它 是 main 方 法 的 参 数, 它 将 包 含 位 于 类 名 之 后 的 命 令 行 中 的 自 变 量 Java HelloWorld args[0] args[1] { 两 个 大 括 号 一 起 中 间 的 内 容 叫 方 法 体, 代 表 这 个 方 法 所 执 行 的 代 码 6. System.out.println (" 你 好, 欢 迎 来 到 Java 快 车!" ); 第 6 行 声 明 如 何 使 用 类 名 对 象 名 和 方 法 调 用 它 使 用 由 System 类 的 out 成 员 引 用 的 PrintStream 对 象 的 println () 方 法, 将 字 串 你 好, 欢 迎 来 到 Java 快 车! 打 印 到 标 准 输 出 上 在 这 个 例 子 中,println() 方 法 被 输 入 了 一 个 字 串 自 变 量 并 将 其 写 在 了 标 准 输 出 流 上 本 程 序 的 7-8 行 分 别 是 方 法 main() 和 类 HelloWorld 的 下 括 号 编 译 并 运 行 HelloWorld 编 译 当 你 创 建 了 HelloWorld.java 源 文 件 后, 用 下 列 命 令 行 进 行 编 译 : 第 20 页

21 javac HelloWorld.java 如 果 编 译 器 未 返 回 任 何 提 示 信 息, 表 示 编 译 完 成, 生 成 一 个 新 文 件 HelloWorld. class, 该 文 件 称 为 字 节 码 文 件,class 文 件 名 和 对 应 的 java 文 件 名 是 相 同 的 class 文 件 被 存 储 在 与 源 文 件 相 同 的 目 录 中, 除 非 另 有 指 定 如 果 在 编 译 中 遇 到 问 题, 请 参 阅 本 模 块 的 查 错 提 示 信 息 部 分 运 行 序 : 为 运 行 你 的 HelloWorld 应 用 程 序, 需 使 用 Java 解 释 器 和 位 于 bin 目 录 下 的 java 程 java HelloWorld 你 好, 欢 迎 来 到 Java 快 车! 编 译 查 错 以 下 是 编 译 时 的 常 见 错 误 : --javac:command not found PATH 变 量 未 正 确 设 置 以 包 括 javac 编 译 器 javac 编 译 器 位 于 JDK 目 录 下 的 bin 目 录 --HelloWorld.java:6: Method printl(java.lang.string) not found in class java.io.printstream.system. out.printl (" 你 好, 欢 迎 来 到 Java 快 车!"); 方 法 名 是 println 而 不 是 printl, 少 敲 了 一 个 n --In class HelloWorld:main must be public or static 该 错 误 的 出 现 是 因 为 main 方 法 没 有 static 或 public 修 饰 符 以 下 是 运 行 时 的 错 误 : --can t find class HelloWorld ( 这 个 错 误 是 在 控 制 台 敲 入 java HelloWorld 时 产 生 的 ) 通 常, 它 表 示 在 命 令 行 中 所 指 定 的 类 名 的 拼 写 与 filename.class 文 件 的 拼 写 不 同 Java 编 程 语 言 是 一 种 大 小 写 区 别 对 待 的 语 言 例 如 : public class Helloworld 创 建 了 一 个 Helloworld.class, 它 不 是 编 译 器 所 预 期 的 类 名 (HelloWorld.class) -- 命 名 如 果.java 文 件 包 括 一 个 公 共 类, 那 么 它 必 须 使 用 与 那 个 公 共 类 相 同 的 文 件 名 例 如 在 前 例 中 的 类 的 定 义 是 public class Helloworld 源 文 件 名 则 必 须 是 Helloworld.java 第 21 页

22 -- 类 的 数 量 在 源 文 件 中 每 次 只 能 定 义 一 个 公 共 类 1.8 Java 的 运 行 过 程 用 一 个 图 来 描 述 这 个 过 程 会 比 较 容 易 理 解 : 编 写 代 码 首 先 把 我 们 想 要 计 算 机 做 的 事 情, 通 过 Java 表 达 出 来, 写 成 Java 文 件, 这 个 过 程 就 是 编 写 代 码 的 过 程 如 上 图 所 示 的 Hello.java 文 件 编 译 写 完 Java 代 码 后, 机 器 并 不 认 识 我 们 写 的 Java 代 码, 需 要 进 行 编 译 成 为 字 节 码, 编 译 后 的 文 件 叫 做 class 文 件 如 上 图 所 示 的 Hello.class 文 件 类 装 载 ClassLoader 类 装 载 的 功 能 是 为 执 行 程 序 寻 找 和 装 载 所 需 要 的 类 ClassLoader 能 够 加 强 代 码 的 安 全 性, 主 要 方 式 是 : 把 本 机 上 的 类 和 网 络 资 源 类 相 分 离, 在 调 入 类 的 时 候 进 行 检 查, 因 而 可 以 限 制 任 何 特 洛 伊 木 马 的 应 用 字 节 码 (byte-code) 校 验 字 节 码 校 验 的 功 能 是 对 class 文 件 的 代 码 进 行 校 验, 保 证 代 码 的 安 全 性 Java 软 件 代 码 在 实 际 运 行 之 前 要 经 过 几 次 测 试 JVM 将 代 码 输 入 一 个 字 节 码 校 验 器 以 测 试 代 码 段 格 式 并 进 行 规 则 检 查 -- 检 查 伪 造 指 针 违 反 对 象 访 问 权 限 或 试 图 改 变 对 象 类 型 的 非 法 代 码 第 22 页

23 字 节 码 校 验 器 对 程 序 代 码 进 行 四 遍 校 验, 这 可 以 保 证 代 码 符 合 JVM 规 范 并 且 不 破 坏 系 统 的 完 整 性 如 果 校 验 器 在 完 成 四 遍 校 验 后 未 返 回 出 错 信 息, 则 下 列 各 点 可 被 保 证 : - 类 符 合 JVM 规 范 的 类 文 件 格 式 - 无 访 问 限 制 异 常 - 代 码 未 引 起 操 作 数 栈 上 溢 或 下 溢 - 所 有 操 作 代 码 的 参 数 类 型 将 总 是 正 确 的 - 无 非 法 数 据 转 换 发 生, 如 将 整 数 转 换 为 对 象 引 用 - 对 象 域 访 问 是 合 法 的 解 释 可 是 机 器 也 不 能 认 识 class 文 件, 还 需 要 被 解 释 器 进 行 解 释, 解 释 成 机 器 码, 计 算 机 的 处 理 器 才 能 最 终 理 解 Java 程 序 员 所 要 表 达 的 指 令 运 行 最 后 由 运 行 环 境 中 的 Runtime 对 指 令 进 行 运 行, 真 正 实 现 我 们 想 要 机 器 完 成 的 工 作 说 明 由 上 面 的 讲 述, 大 家 看 到,Java 通 过 一 个 编 译 阶 段 和 一 个 运 行 阶 段, 来 让 机 器 最 终 理 解 我 们 想 要 它 完 成 的 工 作, 并 按 照 我 们 的 要 求 进 行 运 行 在 这 两 个 阶 段 中, 需 要 我 们 去 完 成 的 就 是 编 译 阶 段 的 工 作, 也 就 是 说 : 我 们 需 要 把 我 们 想 要 机 器 完 成 的 工 作 用 Java 语 言 表 达 出 来, 写 成 Java 源 文 件, 然 后 把 源 文 件 进 行 编 译, 形 成 class 文 件, 最 后 就 可 以 在 Java 运 行 环 境 中 运 行 了 运 行 阶 段 的 工 作 由 Java 平 台 自 身 提 供, 我 们 不 需 要 做 什 么 工 作 1.9 Java 技 术 三 大 特 性 虚 拟 机 Java 虚 拟 机 JVM(Java Virtual Machine) 在 Java 编 程 里 面 具 有 非 常 重 要 的 地 位, 相 当 于 前 面 学 到 的 Java 运 行 环 境, 虚 拟 机 的 基 本 功 能 如 下 : (1) 通 过 ClassLoader 寻 找 和 装 载 class 文 件 (2) 解 释 字 节 码 成 为 指 令 并 执 行, 提 供 class 文 件 的 运 行 环 境 (3) 进 行 运 行 期 间 垃 圾 回 收 (4) 提 供 与 硬 件 交 互 的 平 台 Java 虚 拟 机 是 在 真 实 机 器 中 用 软 件 模 拟 实 现 的 一 种 想 象 机 器 Java 虚 拟 机 代 码 被 存 储 在.class 文 件 中 ; 每 个 文 件 都 包 含 最 多 一 个 public 类 Java 虚 拟 机 规 范 为 不 同 的 硬 件 平 台 提 供 了 一 种 编 译 Java 技 术 代 码 的 规 范, 该 规 范 使 Java 软 件 独 立 于 平 台, 因 为 编 译 是 针 对 作 为 虚 拟 机 的 一 般 机 器 而 做 这 个 一 般 机 器 可 用 软 件 模 拟 并 运 行 于 各 种 现 存 的 计 算 机 系 统, 第 23 页

24 也 可 用 硬 件 来 实 现 编 译 器 在 获 取 Java 应 用 程 序 的 源 代 码 后, 将 其 生 成 字 节 码, 它 是 为 JVM 生 成 的 一 种 机 器 码 指 令 每 个 Java 解 释 器, 不 管 它 是 Java 技 术 开 发 工 具, 还 是 可 运 行 applets 的 Web 浏 览 器, 都 可 执 行 JVM JVM 为 下 列 各 项 做 出 了 定 义 : - 指 令 集 ( 相 当 于 中 央 处 理 器 [CPU]) - 寄 存 器 - 类 文 件 格 式 - 栈 - 垃 圾 收 集 堆 - 存 储 区 JVM 的 代 码 格 式 由 紧 缩 有 效 的 字 节 码 构 成 由 JVM 字 节 码 编 写 的 程 序 必 须 保 持 适 当 的 类 型 约 束 大 部 分 类 型 检 查 是 在 编 译 时 完 成 任 何 从 属 的 Java 技 术 解 释 器 必 须 能 够 运 行 任 何 含 有 类 文 件 的 程 序, 这 些 类 文 件 应 符 合 Java 虚 拟 机 规 范 中 所 指 定 的 类 文 件 格 式 虚 拟 机 是 Java 平 台 无 关 的 保 障 正 是 因 为 有 虚 拟 机 这 个 中 间 层,Java 才 能 够 实 现 与 平 台 无 关 虚 拟 机 就 好 比 是 一 个 Java 运 行 的 基 本 平 台, 所 有 的 Java 程 序 都 运 行 在 虚 拟 机 上, 如 下 图 所 示 : Java 源 程 序 (*.java 文 件 ) javac 编 译 Java 类 文 件 (*.class 文 件 ) 平 台 无 关 被 装 载 进 虚 拟 机 Java 虚 拟 机 相 关 平 台 Linux Windows Unix 垃 圾 回 收 什 么 是 垃 圾 在 程 序 运 行 的 过 程 中, 存 在 被 分 配 了 的 内 存 块 不 再 被 需 要 的 情 况, 那 么 这 些 内 存 块 对 程 序 来 讲 就 是 垃 圾 第 24 页

25 产 生 了 垃 圾, 自 然 就 需 要 清 理 这 些 垃 圾, 更 为 重 要 的 是 需 要 把 这 些 垃 圾 所 占 用 的 内 存 资 源, 回 收 回 来, 加 以 再 利 用, 从 而 节 省 资 源, 提 高 系 统 性 能 垃 圾 回 收 - 不 再 需 要 的 已 分 配 内 存 应 取 消 分 配 ( 释 放 内 存 ) - 在 其 它 语 言 中, 取 消 分 配 是 程 序 员 的 责 任 - Java 编 程 语 言 提 供 了 一 种 系 统 级 线 程 以 跟 踪 内 存 分 配 : 垃 圾 收 集 机 制 - 可 检 查 和 释 放 不 再 需 要 的 内 存 - 可 自 动 完 成 上 述 工 作 许 多 编 程 语 言 都 允 许 在 程 序 运 行 时 动 态 分 配 内 存, 分 配 内 存 的 过 程 由 于 语 言 句 法 不 同 而 有 所 变 化, 但 总 是 要 将 指 针 返 回 到 内 存 的 起 始 位 置, 当 分 配 内 存 不 再 需 要 时 ( 内 存 指 针 已 溢 出 范 围 ), 程 序 或 运 行 环 境 应 释 放 内 存 在 C,C++ 或 其 它 语 言 中, 程 序 员 负 责 释 放 内 存 有 时, 这 是 一 件 很 困 难 的 事 情 因 为 你 并 不 总 是 事 先 知 道 内 存 应 在 何 时 被 释 放 当 在 系 统 中 没 有 能 够 被 分 配 的 内 存 时, 可 导 致 程 序 瘫 痪, 这 种 问 题 被 称 作 内 存 漏 洞 Java 编 程 语 言 解 除 了 程 序 员 释 放 内 存 的 责 任 它 可 提 供 一 种 系 统 级 线 程 以 跟 踪 每 一 次 内 存 的 分 配 情 况 在 Java 虚 拟 机 的 空 闲 周 期, 垃 圾 收 集 线 程 检 查 并 释 放 那 些 可 被 释 放 的 内 存 垃 圾 收 集 在 Java 技 术 程 序 的 生 命 周 期 中 自 动 进 行, 它 解 除 了 释 放 内 存 的 要 求, 这 样 能 够 有 效 避 免 内 存 漏 洞 和 内 存 泄 露 ( 内 存 泄 露 就 是 程 序 运 行 期 间, 所 占 用 的 内 存 一 直 往 上 涨, 很 容 易 造 成 系 统 资 源 耗 尽 而 降 低 性 能 或 崩 溃 ) 提 示 (1) 在 Java 里 面, 垃 圾 回 收 是 一 个 自 动 的 系 统 行 为, 程 序 员 不 需 要 控 制 垃 圾 回 收 的 功 能 和 行 为 比 如 垃 圾 回 收 什 么 时 候 开 始, 什 么 时 候 结 束, 还 有 到 底 哪 些 资 源 需 要 回 收 等 (2) 程 序 员 可 以 通 过 设 置 对 象 为 null( 后 面 会 讲 到 ) 来 标 示 某 个 对 象 不 再 被 需 要 了, 这 只 是 表 示 这 个 对 象 可 以 被 回 收 了, 并 不 是 马 上 被 回 收 (3) 有 一 些 跟 垃 圾 回 收 相 关 的 方 法, 比 如 :System.gc(), 调 用 gc 方 法 暗 示 着 Java 虚 拟 机 做 了 一 些 努 力 来 回 收 未 用 对 象, 以 便 能 够 快 速 地 重 用 这 些 对 象 当 前 占 用 的 内 存 当 控 制 权 从 方 法 调 用 中 返 回 时, 虚 拟 机 已 经 尽 最 大 努 力 从 所 有 丢 弃 的 对 象 中 回 收 了 空 间 代 码 安 全 Java 如 何 保 证 编 写 的 代 码 是 安 全 可 靠 的 呢? 第 一 关 : 编 写 的 代 码 首 先 要 被 编 译 成 为 class 文 件, 如 果 代 码 写 得 有 问 题, 编 译 期 间 就 会 发 现, 然 后 提 示 有 编 译 错 误, 无 法 编 译 通 过 第 25 页

26 第 二 关 : 通 过 编 译 关 后, 在 类 装 载 的 时 候, 还 会 进 行 类 装 载 检 查, 把 本 机 上 的 类 和 网 络 资 源 类 相 分 离, 在 调 入 类 的 时 候 进 行 检 查, 因 而 可 以 限 制 任 何 特 洛 伊 木 马 的 应 用 第 三 关 : 类 装 载 后, 在 运 行 前, 还 会 进 行 字 节 码 校 验, 以 判 断 你 的 程 序 是 安 全 的 第 四 关 : 如 果 你 的 程 序 在 网 络 上 运 行, 还 有 沙 箱 (Sand Box) 的 保 护, 什 么 是 沙 箱 呢? 就 是 如 果 你 的 程 序 没 有 获 得 授 权, 只 能 在 沙 箱 限 定 的 范 围 内 运 行, 是 不 能 够 访 问 本 地 资 源 的, 从 而 保 证 安 全 性 如 下 图 所 示 : 学 习 到 这 里, 大 家 应 该 对 Java 有 了 一 定 的 了 解 了 Java 的 内 容 很 丰 富, 对 于 初 学 者 来 说, 不 可 能 一 次 性 将 所 有 看 到 的 知 识 点 理 解 透 彻 在 学 习 完 第 二 章 后, 对 第 一 章 的 理 解 就 深 入 一 层 ; 学 习 完 第 三 章 后, 对 第 一 章 和 第 二 章 的 理 解 就 又 深 入 一 层 ; 直 到 学 习 完 第 八 章 后, 对 整 个 Java 基 础 才 会 有 比 较 全 面 的 了 解, 所 以 这 并 不 是 一 步 一 个 脚 印 的 学 习 过 程, 而 是 一 个 循 序 渐 进 不 断 加 深 的 学 习 过 程, 需 要 同 学 们 反 复 揣 摩, 体 会 Java 的 思 想 第 26 页

27 1.10 学 习 目 标 学 习 目 标 中 标 注 的 知 识 点 十 分 详 细, 非 常 适 合 初 学 者, 能 帮 助 初 学 者 打 好 坚 实 的 Java 基 础 按 照 学 习 目 标 复 习, 避 免 漏 掉 知 识 点 对 于 标 注 理 解 的, 表 示 能 够 描 述 知 识 点, 就 是 能 对 别 人 讲 解, 能 说 出 相 关 原 因 或 现 象 1. 了 解 Java 语 言 是 什 么 ( 从 四 种 不 同 的 角 度 理 解 Java 语 言 ) 2. 了 解 Java 能 干 什 么 3. 了 解 Java 分 哪 三 个 版 本, 分 别 擅 长 哪 方 面 的 开 发 4. 熟 悉 如 何 构 建 Java 的 开 发 环 境 5. 掌 握 如 何 配 置 环 境 变 量 为 什 么 配 置 这 些 环 境 变 量 6. 掌 握 简 述 开 发 HelloWorld 的 步 骤 7. 能 够 描 述 HelloWorld 的 组 成 部 分 及 中 文 解 释 8. 总 结 在 开 发 HelloWorld 程 序 时 遇 到 的 编 译 错 误 和 运 行 异 常, 并 在 笔 记 中 记 录 下 来 9. 能 够 描 述 Java 程 序 的 运 行 过 程 10. 能 够 描 述 Java 虚 拟 机 的 功 能 11. 能 够 描 述 垃 圾 回 收 机 制 12. 能 够 描 述 Java 代 码 的 安 全 性 第 27 页

28 1.11 练 习 1. 简 述 Java 从 代 码 到 运 行 的 全 过 程 2. 简 述 虚 拟 机 的 工 作 机 制 3. 简 述 Java 的 垃 圾 回 收 机 制 4. 简 述 path classpath JAVA_HOME 各 自 的 含 义 和 配 置 方 式 5. 简 述 软 件 开 发 基 本 步 骤 6. 设 计 一 个 最 简 单 的 输 出 程 序, 要 求 在 屏 幕 上 输 出 以 下 结 果 : 在 Java 快 车 学 习 Java 是 一 个 很 轻 松 的 事 我 很 喜 欢 Java 7. 写 四 个 程 序, 分 别 打 印 一 个 矩 形 一 个 椭 圆 一 个 箭 头 以 及 一 个 菱 形, 如 下 所 示 : 8. 用 8 个 输 出 语 句 显 示 一 个 棋 盘 图 案, 如 下 所 示 : 9. 写 一 个 程 序 计 算 从 0 到 10 的 数 字 的 平 方 和 立 方, 并 按 如 下 格 式 打 印 出 来 : 第 28 页

29 2 基 础 语 法 我 们 在 学 习 汉 语 的 时 候, 开 始 学 的 是 一 些 单 个 的 字, 只 有 认 识 了 单 个 的 字, 然 后 才 能 组 成 词, 然 后 才 能 慢 慢 的 到 句 子, 然 后 到 文 章 学 习 计 算 机 语 言 跟 这 个 过 程 是 一 样 的, 首 先 我 们 要 学 习 一 些 计 算 机 看 得 懂 的 单 个 的 字, 然 后 写 成 一 句 代 码, 最 后 很 多 句 代 码 组 成 程 序 那 么 这 些 单 个 字 在 Java 里 面 就 是 关 键 字, 让 我 们 的 Java 语 法 学 习 从 关 键 字 开 始 吧 2.1 关 键 字 什 么 是 关 键 字 名 关 键 字 对 Java 技 术 编 译 器 有 特 殊 的 含 义, 它 们 可 标 识 数 据 类 型 名 或 程 序 构 造 (construct) 其 实 就 是 个 约 定 或 者 规 定, 比 如 我 们 看 到 红 灯 就 知 道 要 停 下 来, 看 到 绿 灯 就 可 以 前 进 了 这 些 都 是 人 类 约 定 好 的 游 戏 规 则, 在 我 们 的 日 常 生 活 中 有 特 殊 的 意 义, 不 可 改 变, 违 反 它 就 要 付 出 代 价 关 键 字 是 Java 语 言 和 Java 的 开 发 和 运 行 平 台 之 间 的 约 定, 程 序 员 只 要 按 照 这 个 约 定 使 用 了 某 个 关 键 字,Java 的 开 发 和 运 行 平 台 就 能 够 认 识 它, 并 正 确 地 处 理, 展 示 出 程 序 员 想 要 的 效 果 Java 中 的 关 键 字 abstract assert boolean break byte case catch char class continue default do double else enum extends while final finally float for if implements import instanceof int interface long native new void package private protected public return short static super switch synchronized this throw throws transient volatile try strictfp abstract: 表 明 类 或 类 中 的 方 法 是 抽 象 的 ; assert: 声 明 断 言 ; boolean: 基 本 数 据 类 型 之 一, 布 尔 类 型 ; break: 提 前 跳 出 一 个 块 ; byte: 基 本 数 据 类 型 之 一, 字 节 类 型 ; case: 在 switch 语 句 中, 表 明 其 中 的 一 个 分 支 ; catch: 用 于 处 理 例 外 情 况, 用 来 捕 捉 异 常 ; 第 29 页

30 char: 基 本 数 据 类 型 之 一, 字 符 类 型 ; class: 类 ; continue: 回 到 一 个 块 的 开 始 处 ; default: 用 在 switch 语 句 中, 表 明 一 个 默 认 的 分 支 ; do: 用 在 "do while" 循 环 结 构 中 ; double: 基 本 数 据 类 型 之 一, 双 精 度 浮 点 数 类 型 ; else: 在 条 件 语 句 中, 表 明 当 条 件 不 成 立 时 的 分 支 ; extends: 用 来 表 明 一 个 类 是 另 一 个 类 的 子 类 ; final: 用 来 表 明 一 个 类 不 能 派 生 出 子 类, 或 类 中 的 方 法 不 能 被 覆 盖, 或 声 明 一 个 变 量 是 常 量 ; finally: 用 于 处 理 异 常 情 况, 用 来 声 明 一 个 肯 定 会 被 执 行 到 的 块 ; float: 基 本 数 据 类 型 之 一, 单 精 度 浮 点 数 类 型 ; for: 一 种 循 环 结 构 的 引 导 词 ; if: 条 件 语 句 的 引 导 词 ; implements: 表 明 一 个 类 实 现 了 给 定 的 接 口 ; import: 表 明 要 访 问 指 定 的 类 或 包 ; instanceof: 用 来 测 试 一 个 对 象 是 否 是 一 个 指 定 类 的 实 例 ; int: 基 本 数 据 类 型 之 一, 整 数 类 型 ; interface: 接 口 ; long: 基 本 数 据 类 型 之 一, 长 整 数 类 型 ; native: 用 来 声 明 一 个 方 法 是 由 与 机 器 相 关 的 语 言 ( 如 C/C++/FORTRAN 语 言 ) 实 现 的 ; new: 用 来 申 请 新 对 象 ; package: 包 ; private: 一 种 访 问 方 式 : 私 有 模 式 ; protected: 一 种 访 问 方 式 : 保 护 模 式 ; public: 一 种 访 问 方 式 : 公 共 模 式 ; return: 从 方 法 中 返 回 值 ; short: 基 本 数 据 类 型 之 一, 短 整 数 类 型 ; static: 表 明 域 或 方 法 是 静 态 的, 即 该 域 或 方 法 是 属 于 类 的 ; strictfp: 用 来 声 明 FP-strict( 双 精 度 或 单 精 度 浮 点 数 ) 表 达 式, 参 见 IEEE 754 算 术 规 范 ; super: 当 前 对 象 的 父 类 对 象 的 引 用 ; switch: 分 支 结 构 的 引 导 词 ; synchronized: 表 明 一 段 代 码 的 执 行 需 要 同 步 ; this: 当 前 对 象 的 引 用 ; throw: 抛 出 一 个 异 常 ; throws: 声 明 方 法 中 抛 出 的 所 有 异 常 ; transient: 声 明 不 用 序 列 化 的 域 ; try: 尝 试 一 个 可 能 抛 出 异 常 的 程 序 块 void: 表 明 方 法 不 返 回 值 ; volatile: 表 明 两 个 或 多 个 变 量 必 须 同 步 地 发 生 变 化 ; while: 用 在 循 环 结 构 中 ; enum: 声 明 枚 举 类 型 ; 第 30 页

31 说 明 : 1. 这 些 关 键 字 的 具 体 含 义 和 使 用 方 法, 会 在 后 面 使 用 的 时 候 详 细 讲 述 2. Java 的 关 键 字 也 是 随 新 的 版 本 发 布 在 不 断 变 动 中 的, 不 是 一 成 不 变 的 3. 所 有 关 键 字 都 是 小 写 的 2.2 标 识 符 每 个 人 都 有 名 字, 每 个 事 物 也 都 有 名 字, 有 了 名 字, 就 可 以 通 过 语 言 表 示 出 来 Java 的 文 件 类 方 法 变 量 也 都 有 名 字 中 国 人 的 名 字 有 默 认 的 命 名 规 则, 比 如 不 使 用 阿 拉 伯 数 字, 不 使 用 标 点 符 号, 不 使 用 长 辈 的 名 字, 等 等 Java 中 有 什 么 命 名 规 则 呢? 什 么 是 标 识 符 在 Java 编 程 语 言 中, 标 识 符 是 标 识 变 量 类 或 方 法 的 有 效 字 符 序 列 简 单 地 说 标 识 符 就 是 一 个 名 字 标 识 符 命 名 规 则 命 名 规 则 如 下 : (1) 首 字 母 只 能 以 字 母 下 划 线 $ 开 头, 其 后 可 以 跟 字 母 下 划 线 $ 和 数 字 示 例 :$abc _ab ab123 等 都 是 有 效 的 (2) 标 识 符 不 能 是 关 键 字 (3) 标 识 符 区 分 大 小 写 ( 事 实 上 整 个 Java 编 程 里 面 都 是 区 分 大 小 写 的 ) Girl 和 girl 是 两 个 不 同 的 标 识 符 (4) 标 识 符 长 度 没 有 限 制, 但 不 宜 过 长 (5) 如 果 标 识 符 由 多 个 单 词 构 成, 那 么 从 第 二 个 单 词 开 始, 首 字 母 大 写 示 例 :getuser setmodel EmployeeModel 等 (6) 标 识 符 尽 量 命 名 的 有 意 义, 让 人 能 够 望 文 知 意 (7) 尽 量 少 用 带 $ 符 号 的 标 识 符, 主 要 是 习 惯 问 题, 大 家 都 不 是 很 习 惯 使 用 带 $ 符 号 的 标 识 符 ; 还 有 内 部 类 中,$ 具 有 特 殊 的 含 义 (8) 虽 然 Java 语 言 使 用 16-bit 双 字 节 字 符 编 码 标 准 (Unicode 字 符 集 ), 最 多 可 以 识 别 个 字 符 ( ) 建 议 标 识 符 中 最 好 使 用 ASCII 字 母 虽 然 中 文 标 识 符 也 能 够 正 常 编 译 和 运 行, 却 不 建 议 使 用 public class Test { public static void main(string[] args) { String Java 快 车 = " 中 文 标 识 符 测 试 "; System.out.println("Java 快 车 ==" + Java 快 车 ); 运 行 结 果 :Java 快 车 == 中 文 标 识 符 测 试 第 31 页

32 2.2.3 示 例 下 列 哪 些 是 正 确 的 标 识 符 : my Variable 9javakc a+b book1-2-3 java&c It's 错 误 的 标 识 符 及 其 原 因 分 析 如 下 : My Variable // 含 有 空 格 9javakc // 首 字 符 为 数 字 a+b // 加 号 不 是 字 母 book1-2-3 // 减 号 不 是 字 母 java&c // 与 号 不 是 字 母 It's // 单 引 号 不 是 字 母 2.3 数 据 类 型 什 么 叫 数 据 类 型 数 据 类 型 简 单 的 说 就 是 对 数 据 的 分 类, 对 数 据 各 自 的 特 点 进 行 类 别 的 划 分, 划 分 的 每 种 数 据 类 型 都 具 有 区 别 于 其 它 类 型 的 特 征, 每 一 类 数 据 都 有 相 应 的 特 点 和 操 作 功 能 例 如 数 字 类 型 的 就 能 够 进 行 加 减 乘 除 的 操 作 在 现 实 生 活 中, 我 们 通 常 会 针 对 不 同 的 提 问, 做 出 不 同 类 型 的 回 答, 比 如 : 你 叫 什 么 名 字? -- 刘 德 华 你 今 天 多 大 年 纪 了? --24 你 家 住 哪 里? -- 北 京 市 海 淀 区 上 地 信 息 路 请 告 诉 我, 你 的 身 高? 你 带 课 本 了, 是 吗? -- 是 的 1+1=2, 对 吗? -- 对 笑 话? 大 家 仔 细 分 析 一 下 回 答 的 信 息 ( 数 据 ), 是 不 是 有 类 别 之 分? 如 果 类 别 搞 错 了, 是 不 是 会 出 类 似 的 在 程 序 中, 计 算 机 也 需 要 某 种 方 式 来 判 断 某 个 数 字 是 什 么 类 型 的 这 通 常 是 需 要 程 序 员 显 示 来 声 明 某 个 数 据 是 什 么 类 型 的,Java 就 是 这 样 的 Java 是 一 种 强 类 型 的 语 言, 凡 是 使 用 到 的 变 量, 在 编 译 之 前 一 定 要 被 显 示 的 声 明 第 32 页

33 Java 的 安 全 和 健 壮 性 部 分 来 自 于 它 是 强 类 型 语 言 这 一 事 实 首 先, 每 个 变 量 有 类 型, 每 个 表 达 式 有 类 型, 而 且 每 种 类 型 是 严 格 定 义 的 其 次, 所 有 的 数 值 传 递, 不 管 是 直 接 的 还 是 通 过 方 法 调 用 经 由 参 数 传 过 去 的 都 要 先 进 行 类 型 相 容 性 的 检 查 有 些 语 言 没 有 自 动 强 迫 进 行 数 据 类 型 相 容 性 的 检 查 或 对 冲 突 的 类 型 进 行 转 换 的 机 制 Java 编 译 器 对 所 有 的 表 达 式 和 参 数 都 要 进 行 类 型 相 容 性 的 检 查 以 保 证 类 型 是 兼 容 的 任 何 类 型 的 不 匹 配 都 是 错 误 的, 在 编 译 器 完 成 编 译 以 前, 错 误 必 须 被 改 正 Java 数 据 类 型 的 分 类 Java 里 面 的 数 据 类 型 从 大 的 方 面 分 为 两 类, 一 是 基 本 数 据 类 型, 一 是 引 用 类 型 基 本 的 JAVA 数 据 类 型 层 次 图 如 下 : 布 尔 类 型 (boolean) 字 符 型 (char) 基 本 数 据 类 型 定 点 类 型 字 节 型 (byte) 短 整 型 (short) 整 型 (int) 数 据 类 型 数 值 类 型 浮 点 类 型 长 整 型 (long) 单 精 度 (float) 双 精 度 (double) 引 用 数 据 类 型 数 组 接 口 类 Java 中 的 基 本 数 据 类 型 Java 中 的 基 本 数 据 类 型 可 分 为 四 种 : (1) 逻 辑 型 :boolean (2) 文 本 型 :char (3) 整 数 型 :byte short int long (4) 浮 点 型 :float double 第 33 页

34 逻 辑 型 boolean 逻 辑 值 有 两 种 状 态, 即 人 们 经 常 使 用 的 on 和 off 或 true 和 false 或 yes 和 no, 这 样 的 值 是 用 boolean 类 型 来 表 示 的 boolean 有 两 个 文 字 值, 即 true 和 false 以 下 是 一 个 有 关 boolean 类 型 变 量 的 声 明 和 初 始 化 : boolean truth = true; // 声 明 变 量 truth 注 意 : 在 整 数 类 型 和 boolean 类 型 之 间 无 转 换 计 算 有 些 语 言 ( 特 别 值 得 强 调 的 是 C 和 C++) 允 许 将 数 字 值 转 换 成 逻 辑 值 ( 所 谓 非 零 即 真 ), 这 在 Java 编 程 语 言 中 是 不 允 许 的 ; boolean 类 型 只 允 许 使 用 boolean 值 (true 或 false) true 和 false 不 是 关 键 字 文 本 型 char char 类 型 用 来 表 示 单 个 字 符 一 个 char 代 表 一 个 16-bit 无 符 号 的 ( 不 分 正 负 的 ) Unicode 字 符, 一 个 char 字 符 必 须 包 含 在 单 引 号 内 示 例 : 'a' // 表 示 简 单 的 字 符 '1' // 用 数 字 也 可 以 表 示 字 符 下 面 就 错 了, 只 能 使 用 单 个 字 符 'ab' // 错 误 '12' // 错 误 什 么 是 Unicode 编 码 Unicode 编 码 又 叫 统 一 码 万 国 码 或 单 一 码, 是 一 种 在 计 算 机 上 使 用 的 字 符 编 码 它 为 每 种 语 言 中 的 每 个 字 符 设 定 了 统 一 并 且 唯 一 的 二 进 制 编 码, 以 满 足 跨 语 言 跨 平 台 进 行 文 本 转 换 处 理 的 要 求 1990 年 开 始 研 发,1994 年 正 式 公 布 随 着 计 算 机 工 作 能 力 的 增 强,Unicode 也 在 面 世 以 来 的 十 多 年 里 得 到 普 及 Unicode 字 符 集 最 多 可 以 识 别 个 字 符, 每 个 国 建 的 字 母 表 的 字 母 都 是 Unicode 表 中 的 一 个 字 符, 比 如 汉 字 中 的 你 字 就 是 Unicode 表 中 的 第 个 字 符, 还 包 含 日 文 里 的 片 假 名 平 假 名 韩 文 以 及 其 他 语 言 中 的 文 字 在 Java 中 的 定 义 示 例 : char c = 'a'; char c = '1'; 取 值 范 围 和 默 认 值 : 第 34 页

35 名 称 长 度 范 围 默 认 值 char 16 位 0~ '\u0000' Java 里 面 的 转 义 字 符 转 义 字 符 是 指, 用 一 些 普 通 字 符 的 组 合 来 代 替 一 些 特 殊 字 符, 由 于 其 组 合 改 变 了 原 来 字 符 表 示 的 含 义, 因 此 称 为 转 义 常 见 的 转 义 字 符 : \n 回 车 (\u000a) \t 水 平 制 表 符 (\u0009) \b 退 格 (\u0008) \r 换 行 (\u000d) \f 换 页 (\u000c) \' 单 引 号 (\u0027) \" 双 引 号 (\u0022) \\ 反 斜 杠 (\u005c) 整 数 型 byte short int long byte: 字 节 型 short: 短 整 型 int: 整 型 long: 长 整 型 在 Java 中, 整 数 型 的 值 都 是 带 符 号 的 数 字, 可 以 用 十 进 制 八 进 制 和 十 六 进 制 来 表 示 所 谓 几 进 制, 就 是 满 多 少 就 进 位 的 意 思, 如 十 进 制 表 示 逢 十 进 位, 八 进 制 就 表 示 逢 八 进 位 示 例 : 2: 十 进 制 的 2 077: 首 位 的 0 表 示 这 个 一 个 8 进 制 的 数 值, 相 当 于 十 进 制 的 63, 计 算 公 式 :7*8+7=63 0x7C: 首 位 的 0x 表 示 这 个 一 个 16 进 制 的 数 值, 相 当 于 十 进 制 的 124, 计 算 公 式 : 7*16+12=124 在 Java 中 的 定 义 示 例 : 示 例 :byte bt = 5; 表 示 在 Java 中 定 义 一 个 变 量 bt, 类 型 是 byte 类 型, 值 是 5 同 理 可 以 定 义 其 它 的 类 型 : 比 如 : short sh = 5; int i = 5; long lon = 5; 这 些 都 是 可 以 的, 如 果 要 明 确 表 示 是 long 型 的 值, 可 以 在 后 面 直 接 跟 一 个 字 母 L 或 者 l L 表 示 一 个 long 值 也 就 是 写 成 :long abc4 =5L; 请 注 意 : 第 35 页

36 在 Java 编 程 语 言 中 使 用 大 写 或 小 写 L 同 样 都 是 有 效 的, 但 由 于 小 写 l 与 数 字 1 容 易 混 淆, 因 而, 尽 量 不 要 使 用 小 写 整 数 型 的 值, 如 果 没 有 特 别 指 明, 默 认 是 int 型 取 值 范 围 和 默 认 值 : 名 称 长 度 范 围 默 认 值 byte 8 位 -2 7 ~ short 16 位 ~ int 32 位 ~ long 64 位 ~ L 浮 点 型 float double Java 用 浮 点 型 来 表 示 实 数, 简 单 地 说 就 是 带 小 数 的 数 据 用 关 键 字 float 或 double 来 定 义 浮 点 类 型, 如 果 一 个 数 字 包 括 小 数 点 或 指 数 部 分, 或 者 在 数 字 后 带 有 字 母 F 或 f(float) D 或 d(double), 则 该 数 字 文 字 为 浮 点 型 的 示 例 : 12.3 // 浮 点 型 数 据 12.3E10 // 一 个 大 浮 点 数 据,E 或 e 表 示 指 数 值, 相 当 于 12.3*10 10 在 Java 中 的 定 义 示 例 : float f1 = 3.14F; float f2 = 3.14f; double d1 = 3.14; double d2 = 3.14D; double d3 = 3.14d; 请 注 意 : 浮 点 型 的 值, 如 果 没 有 特 别 指, 默 认 是 double 型 的 定 义 float 型 的 时 候, 一 定 要 指 明 是 float 型 的, 可 以 通 过 在 数 字 后 面 添 加 F 或 者 f 来 表 示 定 义 double 型 的 时 候, 可 以 不 用 指 明, 默 认 就 是 double 型 的, 也 可 以 通 过 在 数 字 后 面 添 加 D 或 者 d 来 表 示 取 值 范 围 和 默 认 值 : 名 称 长 度 范 围 默 认 值 float 32 位 0.0f double 64 位 0.0d Java 技 术 规 范 的 浮 点 数 的 格 式 是 由 电 力 电 子 工 程 师 学 会 (IEEE)754 定 义 的, 是 独 立 于 平 台 的 可 以 通 过 Float.MAX_VALUE 和 Float.MIN_VALUE 取 得 Float 的 最 大 最 小 值 ; 可 以 通 过 Double.MAX_VALUE 和 Double.MIN_VALUE 来 取 得 Double 的 最 大 最 小 值 第 36 页

37 特 别 介 绍 : 字 符 串 型 String 字 符 型 只 能 表 示 一 个 字 符, 那 么 多 个 字 符 怎 么 表 示 呢? Java 中 使 用 String 这 个 类 来 表 示 多 个 字 符, 表 示 方 式 是 用 双 引 号 把 要 表 示 的 字 符 串 引 起 来, 字 符 串 里 面 的 字 符 数 量 是 任 意 多 个 字 符 本 身 符 合 Unicode 标 准, char 类 型 的 反 斜 线 符 号 ( 转 义 字 符 ) 适 用 于 String 与 C 和 C++ 不 同,String 不 能 用 \0 作 为 结 束 String 的 文 字 应 用 双 引 号 封 闭, 如 下 所 示 : The quick brown fox jumped over the lazy dog. char 和 String 类 型 变 量 的 声 明 和 初 始 化 如 下 所 示 : char ch = 'A'; // 声 明 并 初 始 化 一 个 字 符 变 量 String str1 = "java 快 车 "; // 字 符 串 类 型 String str2 = ""; // 表 示 空 字 符 串 String str3 = null; // 表 示 空 ( 注 意 不 是 空 字 符 串 ) 注 意 : (1)String 不 是 原 始 的 数 据 类 型, 而 是 一 个 类 (class) (2)String 包 含 的 字 符 数 量 是 任 意 多 个, 而 字 符 类 型 只 能 是 一 个 要 特 别 注 意 : "a" 表 示 的 是 字 符 串, 而 'a' 表 示 的 是 字 符 类 型, 它 们 的 意 义 和 功 能 都 不 同 (3)String 的 默 认 值 是 null 2.4 变 量 和 常 量 变 量 变 量 是 Java 程 序 的 一 个 基 本 存 储 单 元, 它 可 以 用 来 引 用 另 一 个 存 储 单 元 变 量 由 一 个 标 识 符, 类 型 及 一 个 可 选 初 始 值 的 组 合 定 义 此 外, 所 有 的 变 量 都 有 一 个 作 用 域, 定 义 变 量 的 可 见 性, 生 存 期 变 量 的 值 是 可 以 改 变 的, 可 以 通 过 操 作 变 量 来 操 作 变 量 所 对 应 的 内 存 区 域 或 值 块 的 值 a 3 变 量 名 变 量 值 存 储 单 元 3 第 37 页

38 变 量 的 创 建 通 过 声 明 完 成, 执 行 变 量 声 明 语 句 时, 系 统 根 据 变 量 的 数 据 类 型 在 内 存 中 开 辟 相 应 的 存 储 空 间 并 赋 予 初 始 值 来 表 示 赋 值 就 是 为 一 个 声 明 的 变 量 或 者 常 量 赋 予 具 体 的 值, 也 就 是 赋 予 值 的 意 思 使 用 一 个 等 号 = 变 量 的 定 义 规 则 : (1) 遵 从 所 有 标 识 符 的 规 则 (2) 所 有 变 量 都 可 大 小 写 混 用, 但 首 字 符 应 小 写 (3) 尽 量 不 要 使 用 下 划 线 和 $ 符 号 (4) 可 以 先 声 明 再 赋 值, 如 : int i; i=9; 也 可 以 声 明 的 同 时 进 行 赋 值 : int i=9; 这 句 话 的 意 思 就 是, 声 明 一 个 类 型 为 int 的 变 量 i, 并 将 它 赋 值 为 9 (5) 没 有 赋 值 的 变 量 是 不 可 以 使 用 的 如 : int i; System.out.println(i);// 这 句 代 码 是 错 误 的 几 点 说 明 : (1) 变 量 在 计 算 机 内 部 对 应 着 一 个 存 储 单 元, 而 且 总 是 具 有 某 种 数 据 类 型 : 基 本 数 据 类 型 或 引 用 数 据 类 型 (2) 变 量 总 是 具 有 与 其 数 据 类 型 相 对 应 的 值 (3) 每 个 变 量 均 具 有 : 名 字 类 型 一 定 大 小 的 存 储 单 元 以 及 值 (4) 变 量 有 一 个 作 用 范 围, 超 出 它 声 明 语 句 所 在 的 块 就 无 效 常 量 常 量 是 变 量 中 的 一 个 特 例, 用 final 关 键 字 修 饰, 常 量 是 值 是 不 可 以 改 变 的, 也 就 是 说 常 量 引 用 的 存 储 单 元 中 的 数 据 是 不 可 更 改 的 对 常 量 命 名 的 定 义 规 则 : 建 议 大 家 尽 量 全 部 大 写, 并 用 下 划 线 将 词 分 隔 如 :JAVAKC_CLASS PI FILE_PATH 2.5 注 释 什 么 是 注 释 呢? 就 是 标 注 解 释 的 意 思, 主 要 用 来 对 Java 代 码 进 行 说 明 Java 中 有 三 种 注 释 方 式 第 38 页

39 (1)// 注 释 单 行 语 句 示 例 : // 定 义 一 个 值 为 10 的 int 变 量 int a = 10; (2)/* */ 多 行 注 释 示 例 : /* 这 是 一 个 注 释, 不 会 被 Java 用 来 运 行 这 是 第 二 行 注 释, 可 以 有 任 意 多 行 */ (3)/** */ 文 档 注 释 紧 放 在 变 量 方 法 或 类 的 声 明 之 前 的 文 档 注 释, 表 示 该 注 释 应 该 被 放 在 自 动 生 成 的 文 档 中 ( 由 javadoc 命 令 生 成 的 HTML 文 件 ) 以 当 作 对 声 明 项 的 描 述 示 例 : /** * 这 是 一 个 文 档 注 释 的 测 试 * 它 会 通 过 javadoc 生 成 标 准 的 java 接 口 文 档 */ 在 javadoc 注 释 中 加 入 一 个 开 头 的 标 记, 结 合 javadoc 指 令 的 参 数, 可 以 在 生 成 的 API 文 档 中 产 生 特 定 的 标 记 常 用 的 javadoc 标 记 作 版 不 推 荐 使 用 的 方 方 法 的 参 数 类 方 法 的 返 回 类 参 见 ", 用 于 指 定 参 考 的 内 抛 出 的 异 抛 出 的 异 常, 和 exception 同 义 javadoc 标 记 的 应 用 范 围 : 在 类 和 接 口 文 档 注 释 中 的 标 记 @version 在 方 法 或 者 构 造 方 法 中 的 标 记 @throws 在 属 性 文 档 注 释 中 的 标 记 2.6 运 算 符 和 表 达 式 程 序 的 基 本 功 能 是 处 理 数 据, 任 何 编 程 语 言 都 有 自 己 的 运 算 符 为 实 现 逻 辑 和 运 算 要 求, 编 第 39 页

40 程 语 言 设 置 了 各 种 不 同 的 运 算 符, 且 有 优 先 级 顺 序, 所 以 有 的 初 学 者 使 用 复 杂 表 达 式 的 时 候 搞 不 清 楚 下 面 按 优 先 顺 序 列 出 了 各 种 运 算 符 : 优 先 级 运 算 符 分 类 运 算 符 由 高 到 低 一 元 运 算 符 算 术 运 算 符 * / % + - () 关 系 运 算 符 < > <= >= ==!= 逻 辑 运 算 符! && 三 目 运 算 符 布 尔 表 达 式? 表 达 式 1: 表 达 式 2 赋 值 运 算 符 = *= /= %= += -= 表 达 式 是 由 常 量 变 量 对 象 方 法 调 用 和 操 作 符 组 成 的 式 子 表 达 式 必 须 符 合 一 定 的 规 范, 才 可 被 系 统 理 解 编 译 和 运 行 表 达 式 的 值 就 是 对 表 达 式 自 身 运 算 后 得 到 的 结 果 根 据 运 算 符 的 不 同, 表 达 式 相 应 地 分 为 以 下 几 类 : 算 术 表 达 式 关 系 表 达 式 逻 辑 表 达 式 赋 值 表 达 式, 这 些 都 属 于 数 值 表 达 式 一 元 运 算 符 因 操 作 数 是 一 个 故 称 为 一 元 运 算 符 运 算 符 含 义 示 例 - 改 变 数 值 的 符 号, 取 反 -10 -x ++ 左 结 合 ++x; x++; -- 左 结 合 --x; x--; 需 要 注 意 的 是 ++ 或 -- 操 作 : ++x 因 为 ++ 在 前, 所 以 先 加 后 用 x++ 因 为 ++ 在 后, 所 以 先 用 后 加 有 一 种 特 殊 的 情 况 :a+ ++b 和 a+++b 是 不 一 样 的 ( 因 为 有 一 个 空 格 ) int a = 10; int b = 10; int sum = a + ++b; System.out.println("a=" + a + ",b=" + b + ",sum=" + sum); 运 行 结 果 是 : a=10,b=11,sum=21 int a = 10; int b = 10; int sum = a++ + b; 第 40 页

41 System.out.println("a=" + a + ",b=" + b + ",sum=" + sum); 运 行 结 果 是 :a=11,b=10,sum= 算 术 运 算 算 术 运 算 是 指 :+ - * / 等 基 本 运 算 运 算 符 含 义 代 码 示 例 运 算 示 例 + 加 法 x+y 1+2 结 果 :3 ;1.2+1 结 果 :2.2 - 减 法 x-y 1-2 结 果 :-1 ;1.2-1 结 果 :0.2 * 乘 法 x*y 1*2 结 果 :2 ;1.2*1 结 果 :1.2 / 除 法 x/y 5/2 结 果 :2 ;5.2/2 结 果 :2.6 % 求 模 ( 余 ) x%y 5%2 结 果 :1 这 些 操 作 可 以 对 不 同 类 型 的 数 字 进 行 混 合 运 算, 为 了 保 证 操 作 的 精 度, 系 统 在 运 算 过 程 中 会 做 相 应 的 转 化 数 字 精 度 的 问 题, 我 们 在 这 里 不 再 讨 论 下 图 中 展 示 了 运 算 过 程 中, 数 据 自 动 向 上 造 型 的 原 则 1. 实 线 箭 头 表 示 没 有 信 息 丢 失 的 转 换, 也 就 是 安 全 性 的 转 换, 虚 线 的 箭 头 表 示 有 精 度 损 失 的 转 化, 也 就 是 不 安 全 的 2. 当 两 个 操 作 数 类 型 不 相 同 时, 操 作 数 在 运 算 前 会 子 松 向 上 造 型 成 相 同 的 类 型, 再 进 行 运 算 示 例 如 下 : int a = 22; int b = 5; double c = 5.0; System.out.println(b + "+" + c + "=" + (b + c)); //10.0 System.out.println(b + "-" + c + "=" + (b - c)); //0.0 System.out.println(b + "*" + c + "=" + (b * c)); //25.0 System.out.println(a + "/" + b + "=" + (a / b)); //4 System.out.println(a + "%" + b + "=" + (a % b)); //2 System.out.println(a + "/" + c + "=" + (a / c)); //4.4 System.out.println(a + "%" + c + "=" + (a % c)); //2.0 用 加 号 (+) 进 行 串 链 接 第 41 页

42 运 算 符 + 能 够 进 行 String 对 象 的 链 接 并 生 成 一 个 新 的 String: String salutation = "Dr. "; String name = "Jack " + "Arthur"; String title = salutation + name; 最 后 一 行 的 结 果 是 : Dr. Jack Arthur 如 果 + 运 算 符 中 有 一 个 自 变 量 为 String 对 象, 则 其 它 自 变 量 将 被 转 换 成 String 所 有 对 象 都 可 被 自 动 转 换 成 String, 尽 管 这 样 做 的 结 果 可 能 是 意 义 含 糊 的 不 是 字 符 串 的 对 象 是 通 过 使 用 tostring() 成 员 方 法 而 转 换 成 串 的 等 价 物 的 关 系 ( 比 较 ) 运 算 符 Java 具 有 完 备 的 关 系 运 算 符, 这 些 关 系 运 算 符 同 数 学 中 的 关 系 运 算 符 是 一 致 的 具 体 说 明 如 下 : 运 算 符 含 义 示 例 < 小 于 x<y > 大 于 x>y <= 小 于 等 于 x<=y >= 大 于 等 于 x>=y == 等 于 x==y!= 不 等 于 x!=y 关 系 运 算 符 用 于 比 较 两 个 数 据 之 间 的 大 小 关 系, 产 生 的 结 果 都 是 布 尔 型 的 值, 一 般 情 况 下, 在 逻 辑 与 控 制 中 会 经 常 使 用 关 系 运 算 符, 用 于 选 择 控 制 的 分 支, 实 现 逻 辑 要 求 instanceof 操 作 符 用 于 判 断 一 个 引 用 类 型 所 引 用 的 对 象 是 否 是 某 个 指 定 的 类 或 子 类 的 实 例, 如 果 是, 返 回 真 (true), 否 则 返 回 假 (false) 操 作 符 左 边 的 操 作 元 是 一 个 引 用 类 型, 右 边 的 操 作 元 是 一 个 类 名 或 者 接 口, 形 式 如 下 : obj instanceof ClassName 或 者 obj instanceof InterfaceName 需 要 注 意 的 是 : 关 系 运 算 符 中 的 "==" 和 "!=" 既 可 以 操 作 基 本 数 据 类 型, 也 可 以 操 作 引 用 数 据 类 型 操 作 引 用 数 据 类 型 时, 比 较 的 是 引 用 的 内 存 地 址 所 以 在 比 较 非 基 本 数 据 类 型 时, 应 该 使 用 equals 方 法 简 单 示 例 如 下 : public class TestRelation { public static void main(string args[]) { // 变 量 初 始 化 int a = 30; int b = 20; // 定 义 结 果 变 量 boolean r1, r2, r3, r4, r5, r6; 第 42 页

43 // 计 算 结 果 r1 = a == b; r2 = a!= b; r3 = a > b; r4 = a < b; r5 = a >= b; r6 = a <= b; // 输 出 结 果 System.out.println("a = " + a + " b = " + b); System.out.println("a==b = " + r1); System.out.println("a!=b = " + r2); System.out.println("a>b = " + r3); System.out.println("a<b = " + r4); System.out.println("a>=b = " + r5); System.out.println("a<=b = " + r6); 运 行 结 果 如 下 : a = 30 b = 20 a==b = false a!=b = true a>b = true a<b = false a>=b = true a<=b = false 逻 辑 运 算 运 算 符!( 定 义 为 非 ) && ( 定 义 为 与 ) ( 定 义 为 或 ) 执 行 布 尔 逻 辑 表 达 式 逻 辑 非 关 系 值 表 A!A true false false true 逻 辑 与 关 系 值 表 A B A&&B true true true true false false false true false false false false 第 43 页

44 逻 辑 或 关 系 值 表 A B A B true true true true false true false true true false false false 在 运 用 逻 辑 运 算 符 进 行 相 关 的 操 作, 就 不 得 不 说 短 路 现 象 代 码 如 下 : if(1==1 && 1==2 && 1==3){ 代 码 从 左 至 右 执 行, 执 行 第 一 个 逻 辑 表 达 式 后 :true && 1==2 && 1==3 执 行 第 二 个 逻 辑 表 达 式 后 :true && false && 1==3 因 为 其 中 有 一 个 表 达 式 的 值 是 false, 可 以 判 定 整 个 表 达 式 的 值 是 false, 就 没 有 必 要 执 行 第 三 个 表 达 式 了, 所 以 Java 虚 拟 机 不 执 行 1==3 代 码, 就 好 像 被 短 路 掉 了 逻 辑 或 也 存 在 短 路 现 象, 当 执 行 到 有 一 个 表 达 式 的 值 为 true 时, 整 个 表 达 式 的 值 就 为 true, 后 面 的 代 码 就 不 执 行 了 短 路 现 象 在 多 重 判 断 和 逻 辑 处 理 中 非 常 有 用 我 们 经 常 这 样 使 用 : public void a(string str) { if (str!= null && str.trim().length() > 0) { //do some thing; 如 果 str 为 null, 那 么 执 行 str.trim().length() 就 会 报 错, 短 路 现 象 保 证 了 我 们 的 代 码 能 够 正 确 执 行 在 书 写 布 尔 表 达 式 时, 首 先 处 理 主 要 条 件, 如 果 主 要 条 件 已 经 不 满 足, 其 他 条 件 也 就 失 去 了 处 理 的 意 义 也 提 高 了 代 码 的 执 行 效 率 三 目 运 算 三 目 运 算 符 (?:) 相 当 于 条 件 判 断, 表 达 式 x?y:z 用 于 判 断 x 是 否 为 真, 如 果 为 真, 表 达 式 的 值 为 y, 否 则 表 达 式 的 值 为 z 例 如 : public class Test { public static void main(string[] args) { int i = (5 > 3)? 6 : 7; System.out.println("the i=" + i); 运 行 结 果 为 :the i=6 第 44 页

45 其 实 三 目 运 算 符 的 基 本 功 能 相 当 于 if-else( 马 上 就 要 学 到 了 ), 使 用 三 目 运 算 符 是 因 为 它 的 表 达 比 相 同 功 能 的 if-else 更 简 洁 上 面 的 例 子 改 成 用 if-else 表 达 如 下 : public class Test { public static void main(string[] args) { int i = 0; if (5 > 3) { i = 6; else { i = 7; System.out.println("the i=" + i); 运 行 结 果 为 :the i= 赋 值 运 算 符 基 本 的 赋 值 运 算 符 是 = 他 的 优 先 级 别 低 于 其 他 的 运 算 符, 所 以 对 该 运 算 符 往 往 最 后 读 取 一 开 始 可 能 会 以 为 它 是 等 于, 其 实 不 是 的 它 的 作 用 是 将 一 个 表 达 式 的 值 赋 给 一 个 左 值 一 个 表 达 式 或 者 是 一 个 左 值, 或 者 是 一 个 右 值 所 谓 左 值 是 指 一 个 能 用 于 赋 值 运 算 左 边 的 表 达 式 左 值 必 须 能 够 被 修 改, 不 能 是 常 量 我 们 现 在 是 用 变 量 作 左 值, 以 后 还 可 以 看 到, 指 针 和 引 用 也 可 以 作 左 值 例 如 : int a, b, c; a = 3; b = 4; c = (a + b) * (2 * a - b); // 得 出 14 += 是 先 做 加 法 运 算, 再 进 行 赋 值 操 作, 比 如 : int a; a = 3; a += 2;// 得 出 5 其 他 的 赋 值 运 算 符 和 += 类 似 2.7 位 运 算 符 ( 选 修 ) 优 先 级 运 算 符 分 类 运 算 符 由 一 元 运 算 符 ~ 高 移 位 运 算 符 << >> >>> 到 位 运 算 ~ & ^ 低 赋 值 运 算 符 <<= >>= >>>= &= ~= = ^= 第 45 页

46 2.7.1 位 运 算 位 运 算 符 包 括 :&( 与 ), ( 或 ),~( 取 反 ),^( 异 或 ); 位 运 算 是 对 整 数 的 二 进 制 位 进 行 相 关 操 作, 详 细 运 算 如 下 : 非 位 关 系 值 表 A ~A 与 位 关 系 值 表 A B A 或 位 关 系 值 表 A B A 异 或 位 关 系 值 表 A B A 位 运 算 示 例 : int a = 15; int b = 2; System.out.println(a + "&" + b + "=" + (a & b)); System.out.println(a + " " + b + "=" + (a b)); System.out.println(a + "^" + b + "=" + (a ^ b)); System.out.println("~" + b + "=" + (~b)); 第 46 页

47 运 算 结 果 如 下 : 15&2=2 15 2=15 15^2=13 ~2= 移 位 运 算 符 移 位 运 算 符 操 作 的 对 象 就 是 二 进 制 的 位, 可 以 单 独 用 移 位 运 算 符 来 处 理 int 型 或 long 型 整 数, 在 运 算 byte 和 short 类 型 数 据 时, 会 自 动 向 上 造 型 成 int, 再 运 算 运 算 符 含 义 示 例 << 左 移 运 算 符, 将 运 算 符 左 边 的 对 象 向 左 移 动 运 算 符 右 边 指 定 的 位 数 ( 在 低 位 补 0) >> " 有 符 号 " 右 移 运 算 符, 将 运 算 符 左 边 的 对 象 向 右 移 动 运 算 符 右 边 指 定 的 位 数 使 用 符 号 扩 展 机 制, 也 就 是 说, 如 果 值 为 正, 则 在 高 位 补 0, 如 果 值 为 负, 则 在 高 位 补 1. >>> " 无 符 号 " 右 移 运 算 符, 将 运 算 符 左 边 的 对 象 向 右 移 动 运 算 符 右 边 指 定 的 位 数 采 用 0 扩 展 机 制, 也 就 是 说, 无 论 值 的 正 负, 都 在 高 位 补 <<3 : >>3 :12-100>>>3 : 以 int 类 型 的 2039 为 例, 代 码 如 下 : System.out.println(Integer.toBinaryString(2039)); System.out.println(Integer.toBinaryString(-2039)); System.out.println(Integer.toBinaryString(2039 >> 5)); System.out.println(Integer.toBinaryString(-2039 >> 5)); System.out.println(Integer.toBinaryString(2039 >>> 5)); System.out.println(Integer.toBinaryString(-2039 >>> 5)); System.out.println(Integer.toBinaryString(2039 << 5)); System.out.println(Integer.toBinaryString(-2039 << 5)); 第 47 页

48 运 行 结 果 如 下 : 注 意 : 负 数 的 二 进 制 表 现 形 式 是 正 数 取 反 加 一 x<<y 相 当 于 x*2 y ;x>>y 相 当 于 x/2 y 从 计 算 速 度 上 讲, 移 位 运 算 要 比 算 术 运 算 快 如 果 x 是 负 数, 那 么 x>>>3 没 有 什 么 算 术 意 义, 只 有 逻 辑 意 义 移 位 运 算 符 将 它 们 右 侧 的 操 作 数 模 32 简 化 为 int 类 型 左 侧 操 作 数, 模 64 简 化 为 long 类 型 右 侧 操 作 数 因 而, 任 何 int x, x >>> 32 都 会 导 致 不 变 的 x 值, 而 不 是 你 可 能 预 计 的 零 2.8 控 制 语 句 分 支 控 制 语 句 分 支 语 句 又 称 条 件 语 句, 条 件 语 句 使 部 分 程 序 可 根 据 某 些 表 达 式 的 值 被 有 选 择 地 执 行 Java 编 程 语 言 支 持 双 路 if 和 多 路 switch 分 支 语 句 if 语 句 if-else 语 句 的 基 本 句 法 是 : if( 布 尔 表 达 式 ){ 语 句 块 1; else{ 语 句 块 2; 说 明 : (1) 布 尔 表 达 式 返 回 值 为 true 或 false (2) 如 果 为 true, 则 执 行 语 句 或 块 1, 执 行 完 毕 跳 出 if-else 语 句 (3) 如 果 为 false, 则 跳 过 语 句 或 块 1, 然 后 执 行 else 下 的 语 句 或 块 2 第 48 页

49 true 布 尔 表 达 式 false 语 句 块 1 语 句 块 2 例 如 : int a=10; int b=10; if (a >= b) { System.out.println("a 大 于 等 于 b"); else { System.out.println("a 小 于 b"); 在 Java 编 程 语 言 中,if () 用 的 是 一 个 布 尔 表 达 式, 而 不 是 数 字 值, 这 一 点 与 C/C++ 不 同 前 面 已 经 讲 过, 布 尔 类 型 和 数 字 类 型 不 能 相 互 转 换 因 而, 如 果 出 现 下 列 情 况 : if (x) // x 是 int 型 你 应 该 使 用 下 列 语 句 替 代 : if (x! = 0) 注 意 : (1)if 块 和 else 块 可 以 包 含 任 意 的 java 代 码, 自 然 也 就 可 以 包 含 新 的 if-else, 也 就 是 说 :if-else 是 可 以 嵌 套 的, 嵌 套 的 规 则 是 不 可 以 交 叉, 必 须 完 全 包 含 比 如 : if (a1 > a2) { if (a1 > a3) { // 包 含 在 里 面 的 块 必 须 先 结 束 else { // 同 样 可 以 包 含 if-else 块 (2)else 部 分 是 选 择 性 的, 并 且 当 测 试 条 件 为 假 时 如 不 需 做 任 何 事,else 部 分 可 被 省 略 也 就 是 说 if 块 可 以 独 立 存 在, 但 是 else 块 不 能 独 立 存 在, 必 须 要 有 if 块 才 能 有 else 块 (3) 如 果 if 块 和 else 块 的 语 句 只 有 一 句 时, 可 以 省 略 {, 例 如 : if (a1 > a2) System.out.println(" 这 是 if 块 "); 第 49 页

50 else System.out.println(" 这 是 else 块 "); 上 面 的 代 码 从 语 法 角 度 是 完 全 正 确 的, 但 是 从 代 码 的 可 阅 读 性 上, 容 易 让 人 产 生 迷 惑, 所 以 我 们 不 建 议 大 家 这 么 写 例 如 下 : (4) 还 可 以 把 else 和 if 组 合 使 用, 就 是 使 用 else if, 表 达 否 则 如 果 的 意 思, 示 if (score >= 90) { grade = "very good"; else if (score >= 70) { grade = "good"; else if (score >= 60) { grade = "pass"; else { grade = "No pass"; (5) 如 果 不 用 {, 则 else 总 是 与 最 接 近 它 的 前 一 个 if 相 匹 配, 例 如 : if (x > 5) if (y > 5) System.out.println("x and y are > 5"); else System.out.println("x is <= 5"); 执 行 顺 序 与 上 面 的 对 应 匹 配 形 式 不 同, 而 是 与 下 面 形 式 匹 配 if (x > 5) if (y > 5) System.out.println("x and y are > 5"); else System.out.println("x is <= 5"); switch 语 句 switch 表 示 选 择 分 支 的 情 况,switch 语 句 的 句 法 是 : switch ( 表 达 式 1){ case 表 达 式 2: 语 句 块 2; break; case 表 达 式 3: 语 句 块 3; break; default: 语 句 块 4; break; 第 50 页

51 说 明 : (1) 表 达 式 1 的 值 必 须 与 整 型 兼 容 或 者 enum 枚 举 类 型 的 常 量 值, 包 含 byte short int 和 char, 不 能 是 字 符 串 或 对 象, 也 不 能 是 long 型 的 值 (2)case 分 支 要 执 行 的 程 序 语 句 (3) 表 达 式 是 可 能 出 现 的 值 (4) 不 同 的 case 分 支 对 应 着 不 同 的 语 句 或 块 序 列 (5)break 表 示 跳 出 这 一 分 支 (6) 当 变 量 或 表 达 式 的 值 不 能 与 任 何 case 值 相 匹 配 时, 可 选 缺 省 符 (defauit) 指 出 了 应 该 执 行 的 程 序 代 码 示 例 : public class Test { public static void main(string[] args) { int colornum = 5; switch (colornum) { case 0: System.out.println(Color.red); break; case 1: System.out.println(Color.green); break; default: System.out.println(Color.black); break; 运 行 结 果 : java.awt.color[r=0,g=0,b=0] (6) 如 果 没 有 break 语 句 作 为 某 一 个 case 代 码 段 的 结 束 句, 则 程 序 的 执 行 将 继 续 到 下 一 个 case, 而 不 检 查 case 表 达 式 的 值 示 例 : import java.awt.color; public class Test { public static void main(string[] args) { int colornum = 0; switch (colornum) { case 0: System.out.println(Color.red); case 1: 第 51 页

52 System.out.println(Color.green); default: System.out.println(Color.black); break; 运 行 结 果 : java.awt.color[r=255,g=0,b=0] java.awt.color[r=0,g=255,b=0] java.awt.color[r=0,g=0,b=0] 循 环 控 制 语 句 循 环 语 句 使 语 句 或 块 的 执 行 得 以 重 复 进 行 Java 编 程 语 言 支 持 三 种 循 环 构 造 类 型 :for, while 和 do 循 环 for 和 while 循 环 是 在 执 行 循 环 体 之 前 测 试 循 环 条 件, 而 do 循 环 是 在 执 行 完 循 环 体 之 后 测 试 循 环 条 件 这 就 意 味 着 for 和 while 循 环 可 能 连 一 次 循 环 体 都 未 执 行, 而 do 循 环 将 至 少 执 行 一 次 循 环 体 for 循 环 for 循 环 的 句 法 是 : for ( 初 值 表 达 式 ; 测 试 表 达 式 ; 改 变 量 表 达 式 / 步 长 ){ 语 句 块 其 执 行 顺 序 如 下 : (1) 首 先 运 行 初 值 表 达 式 (2) 然 后 计 算 测 试 表 达 式, 如 果 表 达 式 为 true, 执 行 语 句 或 块 ; 如 果 表 达 式 为 false, 退 出 for 循 环 (3) 最 后 执 行 步 长, 第 一 次 循 环 结 束 (4) 第 二 次 循 环 开 始 : 首 先 判 断 测 试 表 达 式, 转 到 第 2 步 继 续 运 行 第 52 页

53 初 值 表 达 式 测 试 表 达 式 false true 语 句 或 块 改 变 量 表 达 式 示 例 : for (int i = 0; i < 10; i++) { System.out.println("Java 快 车 "); System.out.println("Finally!"); 注 意 :for 循 环 的 执 行 顺 序 : 先 执 行 初 始 值 表 达 式 int i = 0; 再 执 行 一 遍 测 试 表 达 式 i < 10; 如 果 测 试 表 达 式 返 回 true, 则 执 行 循 环 体, 就 是 System 的 输 出 语 句, 如 果 测 试 表 达 式 返 回 false, 则 整 个 循 环 结 束, 然 后 执 行 增 量 表 达 式 我 们 称 这 是 第 一 次 循 环 结 束 了, 初 始 值 表 达 式 只 执 行 一 次, 第 二 次 循 环 从 测 试 表 达 式 开 始, 方 法 和 步 骤 和 第 一 次 一 样 循 环 就 这 样 一 次 一 次 地 进 行, 直 到 测 试 表 达 式 返 回 false, 整 个 循 环 就 结 束 了, 这 个 for 语 句 的 生 命 周 期 就 结 束 了 for 语 句 里 面 的 3 个 部 分 都 可 以 省 略, 但 是 我 们 不 建 议 这 么 做 示 例 如 下 : 示 例 1:3 个 部 分 全 部 省 略, 就 是 一 个 无 限 循 环 public class Test { public static void main(string[] args) { for (;;) { System.out.println("Java 快 车 "); 示 例 2: 省 略 测 试 表 达 式 和 增 量 表 达 式 部 分, 就 是 一 个 无 限 循 环 public class Test { public static void main(string[] args) { 第 53 页

54 for (int i = 0;;) { System.out.println("Java 快 车 " + i); 示 例 3: 可 以 省 略 增 量 表 达 式 部 分, 就 是 一 个 无 限 循 环 public class Test { public static void main(string[] args) { for (int i = 0; i < 3;) { System.out.println("Java 快 车 " + i); 示 例 4: 可 以 省 略 增 量 表 达 式 部 分, 就 是 一 个 无 限 循 环 public class Test { public static void main(string[] args) { for (int i = 0;; i++) { System.out.println("Java 快 车 " + i); 示 例 5: 在 for 语 句 的 括 号 里 的 表 达 式 省 略 后, 仍 然 能 完 成 全 部 功 能 public class Test { public static void main(string[] args) { int i = 0; for (;; ) { if(i==10){ // 如 果 条 件 成 立, 使 用 break 跳 出 循 环 break; System.out.println("Java 快 车 " + i); i++; for 循 环 的 组 合 很 多, 要 灵 活 运 行, 避 免 死 循 环 while 循 环 while 循 环 的 句 法 是 : while ( 布 尔 表 达 式 ) { 语 句 块 第 54 页

55 说 明 : 当 布 尔 表 达 式 为 true 时, 执 行 语 句 或 块, 否 则 跳 出 while 循 环 布 尔 表 达 式 false true 语 句 块 示 例 : int i = 0; while (i < 10) { System.out.println("javakc"); i++; System.out.println("Finally!"); 请 确 认 循 环 控 制 变 量 在 循 环 体 被 开 始 执 行 之 前 已 被 正 确 初 始 化, 并 确 认 循 环 控 制 变 量 是 真 时, 循 环 体 才 开 始 执 行 控 制 变 量 必 须 被 正 确 更 新 以 防 止 死 循 环 do-while 循 环 do-while 循 环 的 句 法 是 : do { 语 句 块 ; while ( 测 试 值 表 达 式 ); 说 明 : 先 执 行 语 句 或 块, 然 后 再 判 断 布 尔 表 达 式 与 while 语 句 不 同, 当 布 尔 表 达 式 一 次 都 不 为 true 时,while 语 句 一 开 始 判 断 就 跳 出 循 环, 一 次 都 不 执 行 语 句 或 块, 而 在 do 语 句 中 则 要 执 行 一 次 第 55 页

56 语 句 或 块 true 布 尔 表 达 式 false 示 例 : int i = 0; do { System.out.println("javakc"); i++; while (i < 10); System.out.println("Finally!"); 像 while 循 环 一 样, 请 确 认 循 环 控 制 变 量 在 循 环 体 中 被 正 确 初 始 化 和 测 试 并 被 适 时 更 新 作 为 一 种 编 程 惯 例,for 循 环 一 般 用 在 那 种 循 环 次 数 事 先 可 确 定 的 情 况, 而 while 和 do 用 在 那 种 循 环 次 数 事 先 不 可 确 定 的 情 况 特 殊 循 环 流 程 控 制 下 列 语 句 可 被 用 在 更 深 层 次 的 控 制 循 环 语 句 中 : break [label]; continue[label]; label: 语 句 ;// 这 里 必 须 是 任 意 的 合 法 的 语 句 break 语 句 被 用 来 从 switch 语 句 循 环 语 句 和 预 先 给 定 了 label 的 块 中 退 出, 跳 出 离 break 最 近 的 循 环 continue 语 句 被 用 来 略 过 并 跳 到 循 环 体 的 结 尾, 终 止 本 次 循 环, 继 续 下 一 次 循 环 label 可 标 识 控 制 需 要 转 换 到 的 任 何 有 效 语 句, 它 被 用 来 标 识 循 环 构 造 的 复 合 语 句 当 嵌 套 在 几 层 循 环 中 想 退 出 循 环 时, 正 常 的 break 只 退 出 一 重 循 环, 你 可 以 用 标 号 标 出 你 想 退 出 哪 一 个 语 句 它 类 似 以 前 被 人 诟 病 的 goto 语 句, 我 们 应 该 尽 量 避 免 使 用 例 1:break 的 使 用 public class Test { public static void main(string[] args) { for (int i = 0; i < 10; i++) { if (i == 5) { break; System.out.println("i==" + i); 第 56 页

57 运 行 的 结 果 :i==0 一 直 到 i==4 因 为 当 i==5 的 时 候, 执 行 break, 跳 出 for 循 环 例 2:continue 的 使 用 public class Test { public static void main(string[] args) { for (int i = 0; i < 5; i++) { if (i == 3) { continue; System.out.println("i==" + i); 运 行 的 结 果 :i==0 一 直 到 i==4, 就 是 不 包 括 i==3 因 为 当 i==3 的 时 候, 执 行 continue, 终 止 本 次 循 环, 继 续 下 一 次 循 环 例 3:label 的 使 用 public class Test { public static void main(string[] args) { L: for (int i = 0; i < 5; i++) { if (i == 3) { break L; System.out.println("i==" + i); 运 行 的 结 果 是 :i==0 一 直 到 i==2 在 这 里 看 不 出 执 行 效 果, 如 果 是 两 层 嵌 套 的 循 环, 使 用 label 就 可 以 跳 出 外 层 的 循 环 了 例 4:label 的 使 用 public class Test { public static void main(string[] args) { for (int i = 0; i < 5; i++) { L: if (i == 3) { break L; System.out.println("i==" + i); 运 行 的 结 果 是 :i==0 一 直 到 i==4 例 5:label 的 使 用 public class Test { 第 57 页

58 public static void main(string[] args) { L: for (int i = 0; i < 5; i++) { if (i == 3) { continue L; System.out.println("i==" + i); 运 行 的 结 果 是 :i==0 i==1 i==2 i== 循 环 的 使 用 技 巧 1. 如 果 两 个 或 两 个 以 上 的 for 嵌 套 使 用, 则 执 行 循 环 次 数 多 的 放 最 里 面, 即 执 行 次 数 由 内 到 外 布 局, 这 样 可 以 提 高 执 行 速 度 2. 变 量 的 定 义 等 应 当 尽 量 放 在 for 外 面, 而 不 是 放 里 面 3. 知 道 循 环 次 数 时 使 用 for 循 环, 不 知 道 循 环 次 数 时 使 用 while 循 环 4. 尽 量 使 用 for 而 不 是 while: 因 为 for 初 值, 结 束 条 件, 循 环 增 量 都 放 在 一 起, 看 起 来 方 便 第 58 页

59 2.9 学 习 目 标 1. 了 解 什 么 是 关 键 字? 2. 了 解 学 习 Java 中 的 关 键 字 需 要 注 意 什 么? 3. 了 解 什 么 是 标 识 符? 4. 能 够 描 述 标 识 符 的 命 名 规 则 5. Java 中 数 据 类 型 的 分 类 6. Java 中 有 哪 些 基 本 数 据 类 型 7. 掌 握 8 个 基 本 数 据 类 型 的 范 围, 并 使 用 数 据 类 型 声 明 变 量 8. 深 刻 理 解 Java 中 的 变 量, 变 量 的 赋 值, 变 量 的 存 储 9. 代 码 写 出 Java 中 的 注 释 10. 学 习 Java 中 的 运 算 符, 能 够 说 出 每 种 运 算 符 的 运 算 法 则, 并 能 够 代 码 示 例 11. 描 述 if 语 句 的 句 法 结 构, 能 够 说 出 if 语 句 的 运 行 过 程, 并 能 够 灵 活 使 用 if 语 句 和 if 语 句 的 嵌 套 12. 描 述 switch 语 句 的 句 法 结 构, 能 够 说 出 switch 语 句 的 运 行 过 程, 并 能 够 灵 活 使 用 switch 语 句, 理 解 break 13. 描 述 for 语 句 的 句 法 结 构, 能 够 说 出 for 语 句 的 运 行 过 程, 并 能 够 灵 活 使 用 for 语 句 和 for 语 句 的 嵌 套 14. 描 述 while 语 句 的 句 法 结 构, 能 够 说 出 while 语 句 的 运 行 过 程, 并 能 够 灵 活 使 用 while 语 句 15. 描 述 do-while 语 句 的 句 法 结 构, 能 够 说 出 do-while 语 句 的 运 行 过 程, 并 能 够 灵 活 使 用 do-while 语 句 16. 总 结 循 环 语 句 的 本 质 17. 理 解 循 环 语 句 中 的 break 和 continue, 并 代 码 示 例 18. 理 解 循 环 语 句 中 的 Label, 并 代 码 示 例 第 59 页

60 2.10 练 习 1. 叙 述 标 识 符 的 定 义 规 则, 指 出 下 面 的 标 识 符 中 那 些 是 不 正 确 的, 并 说 明 理 由 here, _there, this, it, 2to1, _it 2. Java 中 有 那 些 基 本 数 据 类 型? 分 别 用 什 么 符 号 来 表 示, 各 自 的 取 值 范 围 是 多 少? 3. 指 出 正 确 的 表 达 式 A. byte b=128; B. char c=65536; C. long len=0xfffl; D. double dd=0.9239d; 4. 下 面 哪 几 个 语 句 将 引 起 编 译 错? A. float f=2039.0; B. double d=2039.0; C. byte b=2039; D. char c=2039; 5. 描 述 短 路 现 象 6. 执 行 下 列 代 码 后 的 x 和 y 的 结 果 分 别 是 什 么? int x,y,a=2; x=a++; y=++a; 7. 下 面 的 程 序 输 出 结 果 是 :a=6 b=5, 请 将 程 序 补 充 完 整 public class A{ public static void main(string args[]){ int a=5,b=6; a= ; b=a-b; a= ; System.out.println("a="+a+ "b="+b); 8. 下 面 哪 个 语 句 序 列 没 有 错 误, 能 够 通 过 编 译? A. int i=0; if(i){ System.out.println("Hi"); 第 60 页

61 B. boolean b=true; boolean b2=true; if(b==b2) { System.out.println("So true"); C. int i=1; int j=2; if(i==1 j==2) System.out.println("OK"); D. int i=1; int j=2; if (i==1 & j==2) System.out.println("OK"); 9. 阅 读 以 下 代 码 行 : boolean a=false; boolean b=true; boolean c=(a&&b)&&(!b); int result= c==false?1:2; 这 段 程 序 执 行 完 后,c 与 result 的 值 是 : A. c=false; result=1; B. c=true; result=2; C. c=true; result=1; D. c=false; result=2; 10. 下 列 代 码 哪 行 会 出 错? 1) public void modify() { 2) int i, j, k; 3) i = 100; 4) while ( i > 0 ) { 5) j = i * 2; 6) System.out.println (" The value of j is " + j ); 7) k = k + 1; 8) i--; 9) 10) A 第 4 行 B 第 6 行 C 第 7 行 D 第 8 行 11. 指 出 下 列 程 序 的 运 行 结 果 int i = 9; switch ( i ) { default: System.out.print("default"); case 0: 第 61 页

62 System.out.print("zero"); break; case 1: System.out.print("one"); case 2: System.out.print("two"); A. default B. defaultzero C. 编 译 错 D. 没 有 任 何 输 出 以 下 是 编 程 题 : 12. 将 1 到 1000 内 的 全 部 数 字 打 印 出 来, 数 字 之 间 用, 分 隔 13. 声 明 两 个 int 类 型 的 变 量 x y, 并 将 分 别 赋 值 给 x y, 比 较 x y 的 大 小, 输 出 其 中 的 大 者 14. 将 1 到 1000 之 间 的 奇 数 打 印 出 来 15. 判 断 一 个 数 能 否 同 时 被 3 和 5 整 除 16. 输 入 三 个 数, 找 出 最 大 一 个 数, 并 打 印 出 来 17. 给 出 一 百 分 制 成 绩, 要 求 输 出 成 绩 等 级 A, B, C, D, E 90 分 以 上 为 A,80~89 分 为 B,70~79 分 为 C,60~69 分 为 D,60 分 以 下 为 E 请 输 入 成 绩 :67 D 请 输 入 成 绩 :89 B 请 输 入 成 绩 :56 D 18. 设 计 一 个 程 序, 输 入 一 个 数 字 (0~6), 用 中 文 显 示 星 期 几 请 输 入 数 字 :6 星 期 日 请 输 入 数 字 :2 星 期 三 请 输 入 数 字 :8 错 误 第 62 页

63 19. 写 一 个 程 序, 要 求 输 入 一 个 数 字, 数 字 中 包 含 5 个 数 位 把 数 字 分 解 成 单 独 的 数 位, 并 打 印 每 一 个 数 位 例 如, 假 定 用 于 键 入 这 个 数 字, 那 么 程 序 应 打 印 结 果 : 某 公 司 计 划 提 高 员 工 工 资, 若 基 本 工 资 大 于 等 于 3000 元, 增 加 工 资 20%; 若 小 于 3000 元 大 于 等 于 2000 元, 则 增 加 工 资 15%; 若 小 于 2000 元 则 增 加 工 资 10% 请 根 据 用 户 输 入 的 基 本 工 资, 计 算 出 增 加 后 的 工 资 请 输 入 员 工 工 资 :3600 现 在 的 工 资 是 :4320 元 请 输 入 员 工 工 资 :2800 现 在 的 工 资 是 :3220 元 请 输 入 员 工 工 资 :1700 现 在 的 工 资 是 :1870 元 21. 设 s=1*2*3*4*5* *n, 求 s 不 大 于 时 最 大 的 n 22. 编 写 程 序, 在 控 制 台 输 出 如 下 图 案 : * ** *** **** * ** *** **** 23. 编 写 一 个 程 序, 说 明 while 和 do/while 的 区 别 24. 使 用 for 语 句 打 印 显 示 下 列 数 字 形 式 :n= 编 程 实 现 求 一 个 十 进 制 数 字 的 二 进 制 形 式 26. 每 位 司 机 都 关 心 车 辆 的 油 耗 情 况 有 位 司 机 记 录 了 自 己 行 使 的 公 里 数, 以 及 每 次 加 油 多 少 升 请 设 计 一 个 程 序, 要 求 输 入 行 使 的 英 里 数, 以 及 每 次 加 了 多 少 升 汽 油 程 序 应 计 算 并 显 示 每 次 加 油 后, 每 升 汽 油 可 供 行 驶 多 少 公 里 程 序 还 应 综 合 所 有 的 输 入, 计 算 并 第 63 页

64 输 出 每 升 汽 油 可 以 供 行 驶 多 少 公 里 输 出 结 果 如 下 : 请 输 入 加 油 量 :30 请 输 入 公 里 数 :300 结 果 : 每 升 油 行 使 10 公 里 平 均 : 每 升 油 行 使 10 公 里 请 输 入 加 油 量 :20 请 输 入 公 里 数 :210 结 果 : 每 升 油 行 使 10.5 公 里 平 均 : 每 升 油 行 使 10.2 公 里 请 输 入 加 油 量 :10 请 输 入 公 里 数 :110 结 果 : 每 升 油 行 使 11 公 里 平 均 : 每 升 油 行 使 公 里 27. 一 家 大 型 化 工 厂 采 用 佣 金 方 式 为 推 销 员 父 薪 酬 推 销 员 每 月 领 到 基 本 工 资 900 元, 再 加 上 一 周 销 售 毛 利 的 9% 例 如, 一 名 推 销 员 在 某 一 周 销 售 了 毛 利 为 5000 元 的 化 工 产 品, 那 么 除 了 领 取 固 定 的 900 元 之 外, 还 要 加 上 5000 元 的 9%, 总 计 1350 元 开 发 一 个 程 序, 用 于 输 入 推 销 员 上 一 周 的 毛 利, 然 后 计 算 并 显 示 那 名 推 销 员 的 收 入 请 输 入 推 销 员 上 一 周 的 毛 利 :6000 推 销 员 的 收 入 是 :1440 元 请 输 入 推 销 员 上 一 周 的 毛 利 :7000 推 销 员 的 收 入 是 :1530 元 请 输 入 推 销 员 上 一 周 的 毛 利 :8000 推 销 员 的 收 入 是 :1620 元 28. 开 发 一 个 程 序, 计 算 每 名 员 工 的 薪 水 公 司 规 定, 每 周 每 名 员 工 在 其 工 作 的 前 40 个 小 时 内, 每 小 时 都 领 取 固 定 工 资 60 元 超 出 40 小 时 后, 每 工 作 一 小 时, 算 一 个 半 小 时 你 的 程 序 根 据 输 入 的 小 时 数, 计 算 并 显 示 员 工 上 一 周 的 薪 水 总 额 第 64 页

65 员 工 上 周 工 作 总 时 间 是 :45 员 工 上 周 的 薪 水 是 :2850 元 员 工 上 周 工 作 总 时 间 是 :50 员 工 上 周 的 薪 水 是 :3300 元 员 工 上 周 工 作 总 时 间 是 :55 员 工 上 周 的 薪 水 是 :3750 元 29. 企 业 发 放 的 奖 金 根 据 利 润 提 成 利 润 (I) 低 于 或 等 于 10 万 元 时, 奖 金 可 提 10%; 利 润 高 于 10 万 元, 低 于 20 万 元 时, 低 于 10 万 元 的 部 分 按 10% 提 成, 高 于 10 万 元 的 部 分, 可 可 提 成 7.5%;20 万 到 40 万 之 间 时, 高 于 20 万 元 的 部 分, 可 提 成 5%;40 万 到 60 万 之 间 时 高 于 40 万 元 的 部 分, 可 提 成 3%;60 万 到 100 万 之 间 时, 高 于 60 万 元 的 部 分, 可 提 成 1.5%, 高 于 100 万 元 时, 超 过 100 万 元 的 部 分 按 1% 提 成, 从 键 盘 输 入 当 月 利 润 I, 求 应 发 放 奖 金 总 数? 第 65 页

66 3 Java 类 和 对 象 3.1 理 解 面 向 对 象 为 什 么 要 面 向 对 象 传 统 的 开 发 方 法 是 面 向 过 程 的, 面 向 过 程 是 一 种 以 事 件 为 中 心 的 编 程 思 想 就 是 分 析 出 解 决 问 题 所 需 要 的 步 骤, 然 后 用 函 数 把 这 些 步 骤 一 步 一 步 实 现, 使 用 的 时 候 一 个 一 个 依 次 调 用 就 可 以 了 面 向 过 程 其 实 是 最 为 实 际 的 一 种 思 考 方 式, 就 是 算 面 向 对 象 的 方 法 也 是 含 有 面 向 过 程 的 思 想, 可 以 说 面 向 过 程 是 一 种 基 础 的 方 法, 它 考 虑 的 是 实 际 的 实 现 一 般 的 面 向 过 程 是 从 上 往 下 步 步 求 精, 当 程 序 规 模 不 是 很 大 时, 面 向 过 程 的 方 法 还 会 体 现 出 一 种 优 势, 因 为 程 序 的 流 程 会 很 清 楚 比 如 拿 学 生 早 上 做 的 事 情 来 说 说 这 种 面 向 过 程, 粗 略 的 可 以 将 过 程 拟 为 : (1) 起 床 (2) 穿 衣 (3) 洗 脸 刷 牙 (4) 去 学 校 这 4 步 就 是 一 步 一 步 的 完 成, 它 的 顺 序 很 重 要, 你 只 须 一 个 一 个 的 实 现 就 行 了 面 向 过 程 开 发 具 有 如 下 缺 点 : 软 件 重 用 性 差 重 用 性 是 指 同 一 事 物 不 经 修 改 或 稍 加 修 改 就 可 多 次 重 复 使 用 的 性 质 软 件 重 用 性 是 软 件 工 程 追 求 的 目 标 之 一 软 件 可 维 护 性 差 软 件 工 程 强 调 软 件 的 可 维 护 性, 强 调 文 档 资 料 的 重 要 性, 规 定 最 终 的 软 件 产 品 应 该 由 完 整 一 致 的 配 置 成 分 组 成 在 软 件 开 发 过 程 中, 始 终 强 调 软 件 的 可 读 性 可 修 改 性 和 可 测 试 性 是 软 件 的 重 要 的 质 量 指 标 实 践 证 明, 用 传 统 方 法 开 发 出 来 的 软 件, 维 护 时 其 费 用 和 成 本 仍 然 很 高, 其 原 因 是 可 修 改 性 差, 维 护 困 难, 导 致 可 维 护 性 差 开 发 出 的 软 件 不 能 满 足 用 户 需 要 用 传 统 的 结 构 化 方 法 开 发 大 型 软 件 系 统 涉 及 各 种 不 同 领 域 的 知 识, 在 开 发 需 求 模 糊 或 需 求 动 态 变 化 的 系 统 时, 所 开 发 出 的 软 件 系 统 往 往 不 能 真 正 满 足 用 户 的 需 要, 用 户 需 求 的 变 化 往 往 造 成 系 统 结 构 的 较 大 变 化, 从 而 需 要 花 费 很 大 代 价 才 能 实 现 这 种 变 化 面 向 对 象 (Object-Oriented, 简 称 OO) 是 一 种 以 事 物 为 中 心 的 编 程 思 想 对 象 是 真 实 世 界 中 的 事 物 在 人 脑 中 的 映 象 在 实 际 生 活 中, 我 们 每 时 每 刻 都 与 对 象 在 打 交 道, 我 们 用 的 钢 笔, 骑 的 自 行 车, 乘 坐 的 公 共 汽 车 等 都 是 对 象 这 些 对 象 是 能 看 得 见 摸 得 着, 第 66 页

67 实 际 存 在 的 东 西, 我 们 称 之 为 实 体 对 象 ; 有 的 对 象 是 针 对 非 具 体 物 体 的, 但 是 在 逻 辑 关 系 上 的 反 映, 比 如 : 钢 笔 与 墨 水 的 关 系, 人 与 自 行 车 的 关 系, 我 们 称 之 为 逻 辑 对 象 如 果 是 用 面 向 对 象 的 方 法 来 模 拟 学 生 早 上 做 的 事 情 可 以 抽 象 出 一 个 学 生 的 类, 它 包 括 四 个 方 法, 但 是 具 体 的 顺 序 就 不 能 体 现 出 来 根 据 类 创 建 一 个 对 象, 再 调 用 对 象 的 方 法, 在 调 用 方 法 时 体 现 出 顺 序 张 三 起 床 张 三 穿 衣 服 张 三 洗 脸 刷 牙 张 三 去 学 校 基 于 对 象 的 编 程 更 符 合 人 的 思 维 模 式, 编 写 的 程 序 更 加 健 壮 和 强 大, 更 重 要 的 是, 面 向 对 象 编 程 鼓 励 创 造 性 的 程 序 设 计 对 象 的 基 本 构 成 现 实 中 的 人 是 一 个 实 体 对 象, 分 析 实 体 对 象 的 构 成, 发 现 有 这 样 一 些 共 同 点, 这 些 实 体 对 象 都 有 自 己 的 状 态 描 述, 比 如 : 人 有 姓 名 身 高 体 重 发 型 着 装 等, 有 了 这 些 描 述, 我 们 可 以 想 象 出 一 个 人 的 样 子 我 们 把 这 些 描 述 称 之 为 属 性, 属 性 是 静 态 的, 这 些 属 性 用 来 决 定 了 对 象 的 具 体 表 现 形 式 除 了 这 些 静 态 的, 实 体 对 象 还 有 自 己 的 动 作, 通 过 这 些 动 作 能 够 完 成 一 定 的 功 能, 我 们 称 之 为 方 法, 比 如 : 人 能 写 字, 能 刷 牙, 能 跑 步, 打 篮 球, 踢 足 球 等 我 们 知 道 了 对 象 的 方 法, 也 就 知 道 了 这 个 对 象 可 以 做 什 么, 有 什 么 用 依 照 这 个 理 论 我 们 再 分 析 一 下 汽 车, 首 先 想 到 的 是 静 态 的 属 性, 有 颜 色 车 牌 号 标 志 发 动 机 的 功 率 乘 载 人 数 自 重 轮 子 数 目 等 等 然 后 是 动 态 的 功 能 : 加 速 减 速 刹 车 转 弯 等 等 总 之 一 句 话, 对 象 同 时 具 备 静 态 的 属 性 和 动 态 的 功 能 如 何 进 行 对 象 抽 象 抽 象 是 在 思 想 上 把 各 种 对 象 或 现 象 之 间 的 共 同 的 本 质 属 性 抽 取 出 来, 而 舍 去 个 别 的 非 本 质 的 属 性 的 思 维 方 法 也 就 是 说 把 一 系 列 相 同 或 类 似 的 实 体 对 象 的 特 点 抽 取 出 来, 采 用 一 个 统 一 的 表 达 方 式, 这 就 是 抽 象 述 : 比 如 : 张 三 这 个 人 身 高 180cm, 体 重 75kg, 会 打 篮 球, 会 跑 步 李 四 这 个 人 身 高 170cm, 体 重 70kg, 会 打 篮 球, 会 跑 步 现 在 想 要 采 用 一 个 统 一 的 类 来 描 述 张 三 和 李 四, 那 么 我 们 就 可 以 采 用 如 下 的 表 述 方 法 来 表 人 { 静 态 属 性 : 姓 名 ; 身 高 ; 第 67 页

68 体 重 ; 动 态 动 作 : 打 篮 球 (); 跑 步 (); Java 中 的 类 和 对 象 Java 中 的 类 把 抽 象 出 来 的 类 型 使 用 Java 表 达 出 来, 那 就 是 类 class 类 是 对 具 有 相 似 性 质 的 一 类 事 物 的 抽 象, 类 封 装 了 一 类 对 象 的 属 性 和 方 法 实 例 化 一 个 类, 可 以 获 得 属 于 该 类 的 一 个 实 例 ( 即 对 象 ) 类 在 Java 编 程 语 言 中 作 为 定 义 新 类 型 的 一 种 途 径, 类 是 组 成 Java 程 序 的 基 本 要 素 类 声 明 可 定 义 新 类 型 并 描 述 这 些 类 型 是 如 何 实 现 的 比 如 前 面 讨 论 过 的 人 汽 车, 使 用 Java 表 达 出 来 就 是 一 个 类 Java 中 的 对 象 样 对 象 是 类 的 一 个 实 例, 类 的 具 体 化, 也 称 实 例 对 象 实 例 就 是 实 际 例 子, 就 好 像 真 实 存 在 一 类 可 被 认 为 是 一 个 模 板 --- 你 正 在 描 述 的 一 个 对 象 模 型 一 个 对 象 就 是 你 每 次 使 用 的 时 候 创 建 的 一 个 类 的 实 例 的 结 果 比 如 前 面 讨 论 的 张 三 和 李 四, 他 们 就 是 通 过 人 这 个 类 的 创 建 出 来 的 实 例, 这 样 就 在 计 算 机 内 存 中, 把 现 实 中 的 张 三 李 四 表 达 出 来 了, 就 像 张 三 李 四 已 经 活 在 计 算 机 的 内 存 中 了 3.2 如 何 使 用 一 个 Java 类 前 面 学 习 了 如 何 定 义 一 个 类, 下 面 来 学 习 如 何 使 用 一 个 类 new 关 键 字 假 如 定 义 了 一 个 表 示 日 期 的 类, 有 三 个 整 数 变 量 ; 日 月 和 年 的 意 义 即 由 这 些 整 数 变 量 给 出 如 下 所 示 : class MyDate { int day; 第 68 页

69 int month; int year; public String tostring() { int num=0; return day+","+month+","+year; 名 称 MyDate 按 照 类 声 明 的 大 小 写 约 定 处 理, 而 不 是 由 语 意 要 求 来 定 在 可 以 使 用 变 量 之 前, 实 际 内 存 必 须 被 分 配 这 个 工 作 是 通 过 使 用 关 键 字 new 来 实 现 的 如 下 所 示 : MyDate mybirth; mybirth = new MyDate() 第 一 个 语 句 ( 声 明 ) 仅 为 引 用 分 配 了 足 够 的 空 间, 而 第 二 个 语 句 则 通 过 调 用 对 象 的 构 造 方 法 为 构 成 MyDate 的 三 个 整 数 分 配 了 空 间 对 象 的 赋 值 使 变 量 mybirth 重 新 正 确 地 引 用 新 的 对 象 这 两 个 操 作 被 完 成 后,MyDate 对 象 的 内 容 则 可 通 过 mybirth 进 行 访 问 关 键 字 new 意 味 着 内 存 的 分 配 和 初 始 化,new 调 用 的 方 法 就 是 类 的 构 造 方 法 假 使 定 义 任 意 一 个 class XXXX, 可 以 调 用 new XXXX() 来 创 建 任 意 多 的 对 象, 对 象 之 间 是 分 隔 的 就 像 有 一 个 汽 车 的 类, 可 以 使 用 new 关 键 字 创 建 多 个 具 体 的 对 象, 比 如 有 红 旗 的 汽 车 奇 瑞 的 汽 车 大 众 的 汽 车 等 等, 它 们 都 是 独 立 的 单 元, 相 互 之 间 是 隔 离 的 一 个 对 象 的 引 用 可 被 存 储 在 一 个 变 量 里, 因 而 一 个 变 量 点 成 员 ( 如 mybirth.day) 可 用 来 访 问 每 个 对 象 的 单 个 成 员 请 注 意 在 没 有 对 象 引 用 的 情 况 下, 仍 有 可 能 使 用 对 象, 这 样 的 对 象 称 作 匿 名 对 象 使 用 一 个 语 句 同 时 为 引 用 mybirth 和 由 引 用 mybirth 所 指 的 对 象 分 配 空 间 也 是 可 能 的 MyDate mybirth = new MyDate(); mybirth 栈 内 存 0x1fb8ee3 day month year 堆 内 存 使 用 对 象 中 的 属 性 和 方 法 要 调 用 对 象 中 的 属 性 和 方 法, 使 用. 操 作 符 对 象 创 建 以 后 就 有 了 自 己 的 属 性, 通 过 使 用. 操 作 符 实 现 对 其 属 性 的 访 问 例 如 : mybirth.day = 26; mybirth.month = 7; mybirth.year = 2000; 第 69 页

70 对 象 创 建 以 后, 通 过 使 用. 操 作 符 实 现 对 其 方 法 的 调 用, 方 法 中 的 局 部 变 量 被 分 配 内 存 空 间, 方 法 执 行 完 毕, 局 部 变 量 即 刻 释 放 内 存 例 如 : mybirth.tostring(); 3.3 Java 类 的 基 本 构 成 一 个 完 整 的 Java 类 通 常 由 下 面 六 个 部 分 组 成 : 包 定 义 语 句 import 语 句 类 定 义 { 成 员 变 量 构 造 方 法 成 员 方 法 其 中 : 只 有 类 定 义 和 { 是 不 可 或 缺 的, 其 余 部 分 都 可 以 根 据 需 要 来 定 义 下 面 分 别 来 学 习 各 个 部 分 的 基 本 规 则, 看 看 如 何 写 Java 的 类, 建 议 初 学 者, 先 看 类 成 员 变 量 方 法 部 分, 再 看 包 import 部 分 包 什 么 是 包 计 算 机 操 作 系 统 使 用 文 件 夹 或 者 目 录 来 存 放 相 关 或 者 同 类 的 文 档, 在 Java 编 程 语 言 中, 提 供 了 一 个 包 的 概 念 来 组 织 相 关 的 类 包 在 物 理 上 就 是 一 个 文 件 夹, 逻 辑 上 代 表 一 个 分 类 概 念 包 是 类 接 口 或 其 它 包 的 集 合, 包 对 类 进 行 有 效 管 理 的 机 制 包 对 于 下 列 工 作 非 常 有 用 : 包 将 包 含 类 代 码 的 文 件 组 织 起 来, 易 于 查 找 和 使 用 适 当 的 类 包 不 止 是 包 含 类 和 接 口, 还 能 够 包 含 其 它 包 形 成 层 次 的 包 空 间 有 助 于 避 免 命 名 冲 突 当 使 用 很 多 类 时, 确 保 类 和 方 法 名 称 的 唯 一 性 是 非 常 困 难 的 包 能 够 形 成 层 次 命 名 空 间, 缩 小 了 名 称 冲 突 的 范 围, 易 于 管 理 名 称 控 制 代 码 访 问 权 限 为 便 于 管 理 数 目 众 多 的 类,Java 语 言 中 引 入 了 包 的 概 念, 可 以 说 是 对 定 义 的 Java 类 进 行 分 组, 将 多 个 功 能 相 关 的 类 定 义 到 一 个 包 中, 以 解 决 命 名 冲 突 引 用 不 方 便 安 全 性 等 问 题 比 如 户 籍 制 度, 每 个 公 民 除 有 自 己 的 名 字 张 三 李 四 外 还 被 规 定 了 他 的 户 籍 地 假 定 有 两 个 人 都 叫 张 三, 只 称 呼 名 字 就 无 法 区 分 他 们, 但 如 果 事 先 登 记 他 们 的 户 籍 分 别 在 北 京 和 上 海, 就 可 以 很 容 易 的 用 北 京 的 张 三 上 海 的 张 三 将 他 们 区 分 开 来 如 果 北 京 市 仍 有 多 个 张 三, 还 可 以 细 分 为 北 京 市. 海 淀 区 的 张 三 北 京 市. 西 城 区. 平 安 大 街 的 张 三 等 等, 直 到 能 惟 一 标 识 每 个 张 三 为 止 第 70 页

71 JDK 中 常 用 的 包 JDK 中 定 义 的 类 就 采 用 了 包 机 制 进 行 层 次 式 管 理, 简 而 言 之 : 从 逻 辑 上 讲, 包 是 一 组 相 关 类 的 集 合 ; 从 物 理 上 讲, 同 包 即 同 目 录 java.lang---- 包 含 一 些 Java 语 言 的 核 心 类, 包 含 构 成 Java 语 言 设 计 基 础 的 类 在 此 包 中 定 义 的 最 重 要 的 一 个 类 是 Object, 代 表 类 层 次 的 根,Java 是 一 个 单 根 系 统, 最 终 的 根 就 是 Object java.awt---- 包 含 了 构 成 抽 象 窗 口 工 具 集 (abstract window toolkits) 的 多 个 类, 这 些 类 被 用 来 构 建 和 管 理 应 用 程 序 的 图 形 用 户 界 面 (GUI) javax.swing---- 完 全 Java 版 的 图 形 用 户 界 面 (GUI) 解 决 方 案, 提 供 了 很 多 完 备 的 组 件, 可 以 应 对 复 杂 的 桌 面 系 统 构 建 等 java.net---- 包 含 执 行 与 网 络 相 关 的 操 作 的 类, 如 URL, Socket, ServerSocket java.io---- 包 含 能 提 供 多 种 输 入 / 输 出 功 能 的 类 java.util---- 包 含 一 些 实 用 工 具 类, 如 定 义 系 统 特 性 使 用 与 日 期 日 历 相 关 的 方 法 还 有 重 要 的 集 合 框 架 代 码 中 如 何 表 达 包 Java 语 言 使 用 package 语 句 来 实 现 包 的 定 义 package 语 句 必 须 作 为 Java 源 文 件 的 非 注 释 语 句 第 一 条 语 句, 指 明 该 文 件 中 定 义 的 类 所 在 的 包 若 缺 省 该 语 句, 则 指 定 为 无 名 包, 其 语 法 格 式 为 : package pkg1[.pkg2[.pkg3 ]]; // [] 表 示 可 选 Java 编 译 器 把 包 对 应 于 文 件 系 统 的 目 录 管 理, 因 此 包 也 可 以 嵌 套 使 用, 即 一 个 包 中 可 以 含 有 类 的 定 义 也 可 以 含 有 子 包, 其 嵌 套 层 数 没 有 限 制 package 语 句 中, 用. 来 指 明 包 的 层 次 程 序 中 package 的 使 用 :Test.java package p1; public class Test { public void display() { System.out.println("in method display()"); Java 语 言 要 求 包 声 明 的 层 次 和 实 际 保 存 类 的 字 节 码 文 件 的 目 录 结 构 存 在 对 应 关 系, 以 便 将 来 使 用 该 类 时 能 通 过 包 名 ( 也 就 是 目 录 名 ) 查 找 到 所 需 要 的 类 文 件 简 单 地 说 就 是 包 的 层 次 结 构 第 71 页

72 需 要 和 文 件 夹 的 层 次 对 应 注 意 : 每 个 源 文 件 只 有 一 个 包 的 声 明, 而 且 包 名 应 该 全 部 小 写 编 译 和 生 成 包 如 果 在 程 序 Test.java 中 已 定 义 了 包 p1, 就 必 须 将 编 译 生 成 的 字 节 码 文 件 Test.class 保 存 在 与 包 名 同 名 的 子 目 录 中, 可 以 选 用 下 述 两 种 方 式 之 一 : 直 接 编 译 : javac Test.java 则 编 译 器 会 在 当 前 目 录 下 生 成 Test.class 文 件, 再 在 手 动 创 建 一 个 名 为 p1 的 文 件 夹, 将 Test.class 复 制 到 该 p1 目 录 下 带 包 编 译 : 带 包 编 译 是 简 化 的 编 译 命 令 javac -d.\ Test.java 编 译 器 会 自 动 在 当 前 目 录 下 建 立 一 个 子 目 录 p1, 并 将 生 成 的.class 文 件 自 动 保 存 到 p1 文 件 夹 下 javac -d.\test\ Test.java 编 译 器 会 自 动 在 当 前 目 录 下 的 test 文 件 夹 中 建 立 一 个 子 目 录 p1, 并 将 生 成 的.class 文 件 自 动 保 存 到 p1 文 件 夹 下 前 提 是 当 前 目 录 下 必 须 有 test 文 件 夹, 否 则 报 错 : 未 找 到 目 录 :.\test\ javac -d D:\test\ Test.java 编 译 器 会 自 动 在 D 盘 根 目 录 下 的 test 文 件 夹 中 建 立 一 个 子 目 录 p1, 并 将 生 成 的.class 文 件 自 动 保 存 到 p1 文 件 夹 下 前 提 是 D 盘 根 目 录 下 必 须 有 test 文 件 夹, 否 则 报 错 : 未 找 到 目 录 :D:\test\ 带 包 运 行 运 行 带 包 的 程 序, 需 要 使 用 类 的 全 路 径, 也 就 是 带 包 的 路 径, 比 如 上 面 的 那 个 程 序, 就 使 用 如 下 的 代 码 进 行 运 行 : java p1.test import 语 句 用 法 为 了 能 够 使 用 某 一 个 包 的 成 员, 我 们 需 要 在 Java 程 序 中 明 确 导 入 该 包 使 用 import 语 句 可 完 成 此 功 能 在 java 源 文 件 中 import 语 句 应 位 于 package 语 句 之 后, 所 有 类 的 定 义 之 前, 可 以 没 有, 也 可 以 有 多 条, 其 语 法 格 式 为 : 第 72 页

73 import package1[.package2 ].(classname *); java 运 行 时 环 境 将 到 CLASSPATH + package1.[package2 ] 路 径 下 寻 找 并 载 入 相 应 的 字 节 码 文 件 classname.class * 号 为 通 配 符, 代 表 所 有 的 类 也 就 是 说 import 语 句 为 编 译 器 指 明 了 寻 找 类 的 途 径 例, 使 用 import 语 句 引 入 类 程 序 :TestPackage.java import p1.test; // 或 者 import p1.*; public class TestPackage { public static void main(string args[]) { Test t = new Test(); // Test 类 在 p1 包 中 定 义 t.display(); java 编 译 器 默 认 为 所 有 的 java 程 序 引 入 了 JDK 的 java.lang 包 中 所 有 的 类 (import java.lang.*;), 其 中 定 义 了 一 些 常 用 类 :System String Object Math 等 因 此 我 们 可 以 直 接 使 用 这 些 类 而 不 必 显 式 引 入 但 使 用 其 它 非 无 名 包 中 的 类 则 必 须 先 引 入 后 使 用 访 问 修 饰 符 Java 语 言 允 许 对 类 中 定 义 的 各 种 属 性 和 方 法 进 行 访 问 控 制, 即 规 定 不 同 的 保 护 等 级 来 限 制 对 它 们 的 使 用 为 什 么 要 这 样 做?Java 语 言 引 入 类 似 访 问 控 制 机 制 的 目 的 在 于 实 现 信 息 的 封 装 和 隐 藏 Java 语 言 为 对 类 中 的 属 性 和 方 法 进 行 有 效 地 访 问 控 制, 将 它 们 分 为 四 个 等 级 : private 无 修 饰 符 protected public, 具 体 规 则 如 下 : 变 量 和 方 法 可 以 使 用 四 个 访 问 级 别 中 的 任 意 一 个 修 饰, 类 可 以 使 用 公 共 或 无 修 饰 级 别 修 饰 变 量 方 法 或 类 有 缺 省 ( 无 修 饰 符 ) 访 问 性, 如 果 它 没 有 显 式 受 保 护 修 饰 符 作 为 它 的 声 明 的 一 部 分 的 话 这 种 访 问 性 意 味 着, 访 问 可 以 来 自 任 何 方 法, 当 然 这 些 方 法 只 能 在 作 为 对 象 的 同 一 个 包 中 的 成 员 类 当 中 以 修 饰 符 protected 标 记 的 变 量 或 方 法 实 际 上 比 以 缺 省 访 问 控 制 标 记 的 更 易 访 问 一 个 protected 方 法 或 变 量 可 以 从 同 一 个 包 中 的 类 当 中 的 任 何 方 法 进 行 访 问, 也 可 以 是 从 任 何 子 类 第 73 页

74 中 的 任 何 方 法 进 行 访 问 当 它 适 合 于 一 个 类 的 子 类 但 不 是 不 相 关 的 类 时, 就 可 以 使 用 这 种 受 保 护 访 问 来 访 问 成 员 类 定 义 Java 程 序 的 基 本 单 位 是 类, 你 建 立 类 之 后, 就 可 用 它 来 建 立 许 多 你 需 要 的 对 象 Java 把 每 一 个 可 执 行 的 成 分 都 变 成 类 类 的 定 义 形 式 如 下 : < 权 限 修 饰 符 > [ 一 般 修 饰 符 ] class < 类 名 > [extends 父 类 ][implements 接 口 ]{ [< 属 性 定 义 >] [< 构 造 方 法 定 义 >] [< 方 法 定 义 >] 这 里, 类 名 要 是 合 法 的 标 识 符 在 类 定 义 的 开 始 与 结 束 处 必 须 使 用 花 括 号 你 也 许 想 建 立 一 个 矩 形 类, 那 么 可 以 用 如 下 代 码 : public class Rectangle{...// 矩 形 具 体 的 属 性 和 方 法 构 造 方 法 什 么 是 构 造 方 法 类 有 一 个 特 殊 的 成 员 方 法 叫 作 构 造 方 法, 它 的 作 用 是 创 建 对 象 并 初 始 化 成 员 变 量 在 创 建 对 象 时, 会 自 动 调 用 类 的 构 造 方 法 构 造 方 法 定 义 规 则 Java 中 的 构 造 方 法 必 须 与 该 类 具 有 相 同 的 名 字, 并 且 没 有 方 法 的 返 回 类 型 ( 包 括 没 有 void) 另 外, 构 造 方 法 一 般 都 应 用 public 类 型 来 说 明, 这 样 才 能 在 程 序 任 意 的 位 置 创 建 类 的 实 例 -- 对 象 下 面 是 一 个 Rectangle 类 的 构 造 方 法, 它 带 有 两 个 参 数, 分 别 表 示 矩 形 的 长 和 宽 : public class Rectangle { int width; int height; public Rectangle(int w, int h) { width = w; height = h; public Rectangle() { 第 74 页

75 每 个 类 至 少 有 一 个 构 造 方 法 如 果 不 写 一 个 构 造 方 法,Java 编 程 语 言 将 提 供 一 个 默 认 的, 该 构 造 方 法 没 有 参 数, 而 且 方 法 体 为 空 注 意 : 如 果 一 个 类 中 已 经 定 义 了 构 造 方 法 则 系 统 不 再 提 供 默 认 的 构 造 方 法 析 构 方 法 ( 选 修 ) 当 垃 圾 回 收 器 将 要 释 放 无 用 对 象 的 内 存 时, 先 调 用 该 对 象 的 finalize() 方 法 如 果 在 程 序 终 止 前 垃 圾 回 收 器 始 终 没 有 执 行 垃 圾 回 收 操 作, 那 么 垃 圾 回 收 器 将 始 终 不 会 调 用 无 用 对 象 的 finalize() 方 法 在 Java 的 Object 基 类 中 提 供 了 protected 类 型 的 finalize() 方 法, 因 此 任 何 Java 类 都 可 以 覆 盖 finalize() 方 法, 通 常, 在 析 构 方 法 中 进 行 释 放 对 象 占 用 的 相 关 资 源 的 操 作 Java 虚 拟 机 的 垃 圾 回 收 操 作 对 程 序 完 全 是 透 明 的, 因 此 程 序 无 法 预 料 某 个 无 用 对 象 的 finalize() 方 法 何 时 被 调 用 如 果 一 个 程 序 只 占 用 少 量 内 存, 没 有 造 成 严 重 的 内 存 需 求, 垃 圾 回 收 器 可 能 没 有 释 放 那 些 无 用 对 象 占 用 的 内 存, 因 此 这 些 对 象 的 finalize() 方 法 还 没 有 被 调 用, 程 序 就 终 止 了 程 序 即 使 显 式 调 用 System.gc() 或 Runtime.gc() 方 法, 也 不 能 保 证 垃 圾 回 收 操 作 一 定 执 行, 也 就 不 能 保 证 对 象 的 finalize() 方 法 一 定 被 调 用 当 垃 圾 回 收 器 在 执 行 finalize() 方 法 的 时 候, 如 果 出 现 了 异 常, 垃 圾 回 收 器 不 会 报 告 异 常, 程 序 继 续 正 常 运 protected void finalize(){ System.out.println("in finalize"); 在 Java 编 程 里 面, 一 般 不 需 要 我 们 去 写 析 构 方 法, 这 里 只 是 了 解 一 下 就 可 以 了 成 员 变 量 成 员 变 量 是 指 类 的 一 些 属 性 定 义, 标 志 类 的 静 态 特 征, 它 的 基 本 格 式 如 下 : < 权 限 修 饰 符 > [ 一 般 修 饰 符 ] 类 型 < 属 性 名 称 > [= 初 始 值 ]; 访 问 修 饰 符 : 可 以 使 用 四 种 不 同 的 访 问 修 饰 符 中 的 一 种, 包 括 public( 公 共 的 ) protected( 受 保 护 的 ), 无 修 饰 符 和 private( 私 有 的 ) public 访 问 修 饰 符 表 示 属 性 可 以 从 任 何 其 它 代 码 调 用 private 表 示 属 性 只 可 以 由 该 类 中 的 其 它 方 法 来 调 用 protected 将 在 以 后 的 课 程 中 讨 论 修 饰 符 : 是 对 属 性 特 性 的 描 述, 例 如 后 面 会 学 习 到 的 :static final 等 等 类 型 : 属 性 的 数 据 类 型, 可 以 是 任 意 的 类 型 第 75 页

76 属 性 名 称 : 任 何 合 法 标 识 符 初 始 值 : 赋 值 给 属 性 的 初 始 值 如 果 不 设 置, 那 么 会 自 动 进 行 初 始 化, 基 本 类 型 使 用 缺 省 值, 对 象 类 型 自 动 初 始 化 为 null 成 员 变 量 有 时 候 也 被 称 为 属 性 实 例 变 量 方 法 定 义 方 法 就 是 对 象 所 具 有 的 动 态 功 能 Java 类 中 方 法 的 声 明 采 用 以 下 格 式 : < 权 限 修 饰 符 > [ 修 饰 符 ] 返 回 值 类 型 < 方 法 名 称 > ( 参 数 列 表 ) [throws 异 常 列 表 ]{ [ 方 法 体 ] 访 问 修 饰 符 : 可 以 使 用 四 种 不 同 的 访 问 修 饰 符 中 的 一 种, 包 括 public protected 无 修 饰 符 和 private public 访 问 修 饰 符 表 示 方 法 可 以 从 任 何 其 它 代 码 调 用 private 表 示 方 法 只 可 以 由 该 类 中 的 其 它 方 法 来 调 用 protected 将 在 以 后 的 课 程 中 讨 论 修 饰 符 : 是 对 方 法 特 性 的 描 述, 例 如 后 面 会 学 习 到 的 :static final abstract synchronized 等 等 返 回 值 类 型 : 表 示 方 法 返 回 值 的 类 型 如 果 方 法 不 返 回 任 何 值, 它 必 须 声 明 为 void( 空 ) Java 技 术 对 返 回 值 是 很 严 格 的, 例 如, 如 果 声 明 某 方 法 返 回 一 个 int 值, 那 么 方 法 必 须 从 所 有 可 能 的 返 回 路 径 中 返 回 一 个 int 值 ( 只 能 在 等 待 返 回 该 int 值 的 上 下 文 中 被 调 用 ) 方 法 名 称 : 可 以 是 任 何 合 法 标 识 符, 并 带 有 用 已 经 使 用 的 名 称 为 基 础 的 某 些 限 制 条 件 参 数 列 表 : 允 许 将 参 数 值 传 递 到 方 法 中 列 举 的 元 素 由 逗 号 分 开, 而 每 一 个 元 素 包 含 一 个 类 型 和 一 个 标 识 符 在 下 面 的 方 法 中 只 有 一 个 形 式 参 数, 用 int 类 型 和 标 识 符 days 来 声 明 : public void test(int days){ throws 异 常 列 表 : 子 句 导 致 一 个 运 行 时 错 误 ( 异 常 ) 被 报 告 到 调 用 的 方 法 中, 以 便 以 合 适 的 方 式 处 理 它 异 常 在 后 面 的 课 程 中 介 绍 花 括 号 内 是 方 法 体, 即 方 法 的 具 体 语 句 序 列 示 例 比 如 现 在 有 一 个 车 的 类 Car, 车 具 有 一 些 基 本 的 属 性, 比 如 四 个 轮 子, 一 个 方 向 盘, 车 的 品 牌 等 等 当 然, 车 也 具 有 自 己 的 功 能, 也 就 是 方 法, 比 如 车 能 够 开 动 run 要 想 车 子 能 够 开 动, 需 要 给 车 子 添 加 汽 油, 也 就 是 说, 需 要 为 run 方 法 传 递 一 些 参 数 油 进 去 车 子 就 可 以 跑 起 来, 这 些 油 可 以 供 行 驶 多 少 公 里? 就 需 要 run 方 法 具 有 返 回 值 行 驶 里 程 数 第 76 页

77 package com.javakc; public class Car {// 车 这 个 类 private String make;// 一 个 车 的 品 牌 private int tyre;// 一 个 车 具 有 轮 胎 的 个 数 private int wheel;// 一 个 车 具 有 方 向 盘 的 个 数 public Car() { // 初 始 化 属 性 make = "BMW";// 车 的 品 牌 是 宝 马 tyre = 4;// 一 个 车 具 有 4 个 轮 胎 wheel = 1;// 一 个 车 具 有 一 个 方 向 盘 /** * 车 这 个 对 象 所 具 有 的 功 能, 能 够 开 动 * oil 为 车 辆 加 汽 油 的 数 量 车 辆 行 驶 的 公 里 数 */ public double run(int oil) { // 进 行 具 体 的 功 能 处 理 return 100*oil/8; public static void main(string[] args){ Car c=new Car(); double mileage=c.run(100); System.out.println(" 行 驶 了 "+mileage+" 公 里 "); main 方 法 是 一 个 特 殊 的 方 法, 如 果 按 照 public static void main(string[] args) 的 格 式 写, 它 就 是 一 个 类 的 入 口 方 法, 也 叫 主 函 数 当 这 个 类 被 java 指 令 执 行 的 时 候, 首 先 执 行 的 是 main 方 法, 如 果 一 个 类 没 有 入 口 方 法, 就 不 能 使 用 java 指 令 执 行 它, 但 可 以 通 过 其 他 的 方 法 调 用 它 形 参 和 实 参 对 于 方 法 的 参 数 的 理 解, 分 为 形 参 和 实 参 : 形 参 : 就 是 形 式 参 数 的 意 思 是 在 定 义 方 法 的 时 候 使 用 的 参 数, 用 来 标 识 方 法 接 收 的 参 数 类 型, 在 调 用 该 方 法 时 传 入 实 参 : 就 是 实 际 参 数 的 意 思 是 在 调 用 方 法 时 传 递 给 该 方 法 的 实 际 参 数 比 如 : 上 面 的 例 子 中 int oil 就 是 个 形 式 参 数, 这 里 只 是 表 示 需 要 加 入 汽 油, 这 个 方 法 才 能 正 常 运 行, 但 具 体 加 入 多 少, 要 到 真 正 使 用 的 时 候, 也 就 是 调 用 这 个 方 法 的 时 候 才 具 体 确 定, 加 入 调 用 的 时 候 传 入 100, 这 就 是 个 实 际 参 数 形 参 和 实 参 有 如 下 基 本 规 则 : 第 77 页

78 形 参 和 实 参 的 类 型 必 须 要 一 致, 或 者 要 符 合 隐 含 转 换 规 则 形 参 类 型 不 是 引 用 类 型 时, 在 调 用 该 方 法 时, 是 按 值 传 递 的 在 该 方 法 运 行 时, 形 参 和 实 参 是 不 同 的 变 量, 它 们 在 内 存 中 位 于 不 同 的 位 置, 形 参 将 实 参 的 值 复 制 一 份, 在 该 方 法 运 行 结 束 的 时 候 形 参 被 释 放, 而 实 参 内 容 不 会 改 变 形 参 类 型 是 引 用 类 型 时, 在 调 用 该 方 法 时, 是 按 引 用 传 递 的 运 行 时, 传 给 方 法 的 是 实 参 的 地 址, 在 方 法 体 内 部 使 用 的 也 是 实 参 的 地 址, 即 使 用 的 就 是 实 参 本 身 对 应 的 内 存 空 间 所 以 在 函 数 体 内 部 可 以 改 变 实 参 的 值 参 数 可 变 的 方 法 ( 选 修 ) 从 JDK5.0 开 始, 提 供 了 参 数 可 变 的 方 法 当 不 能 确 定 一 个 方 法 的 入 口 参 数 的 个 数 时,5.0 以 前 版 本 的 Java 中, 通 常 的 做 法 是 将 多 个 参 数 放 在 一 个 数 组 或 者 对 象 集 合 中 作 为 参 数 来 传 递,5.0 版 本 以 前 的 写 法 是 : Int sum(integer[] numbers){ // 在 另 一 个 方 法 中 调 用 该 方 法 sum(new Integer[] {12,13,20); 而 在 5.0 版 本 中 可 以 写 为 : // 注 意 : 方 法 定 义 中 是 三 个 点 int sum(integer... numbers){ // 方 法 内 的 操 作 // 调 用 该 方 法 sum(12,13,20);// 正 确 sum(10,11); // 正 确 也 就 是 说, 传 入 参 数 的 个 数 并 不 确 定 但 请 注 意 : 传 入 参 数 的 类 型 必 须 是 一 致 的, 究 其 本 质, 就 是 一 个 数 组 显 然,JDK5.0 版 本 的 写 法 更 为 简 易, 也 更 为 直 观, 尤 其 是 方 法 的 调 用 语 句, 不 仅 简 化 很 多, 而 且 更 符 合 通 常 的 思 维 方 式, 更 易 于 理 解 3.4 this 关 键 字 关 键 字 this 是 用 来 指 向 当 前 对 象 或 类 实 例 的, 功 能 说 明 如 下 : 点 取 属 性 this.day 指 的 是 调 用 当 前 对 象 的 day 字 段, 示 例 如 下 : public class MyDate { private int day, month, year; public void tomorrow() { 第 78 页

79 this.day = this.day + 1; // 其 他 代 码 Java 编 程 语 言 自 动 将 所 有 实 例 变 量 和 方 法 引 用 与 this 关 键 字 联 系 在 一 起, 因 此,this 可 以 省 略 下 面 的 代 码 与 前 面 的 代 码 是 等 同 的 public class MyDate { private int day, month, year; public void tomorrow() { day = day + 1; // 在 day 前 面 没 有 使 用 this // 其 他 代 码 在 类 属 性 上 定 义 的 变 量 和 方 法 内 部 定 义 的 变 量 相 同 的 时 候, 到 底 是 调 用 谁? 例 如 : public class Test { int i = 2; public void t() { int i = 3; // 跟 属 性 的 变 量 名 称 是 相 同 的 System.out.println(" 实 例 变 量 i=" + this.i); System.out.println(" 方 法 内 部 的 变 量 i=" + i); 也 就 是 说 : this. 变 量 调 用 的 是 当 前 属 性 的 变 量 值, 直 接 使 用 变 量 名 称 调 用 的 是 相 对 距 离 最 近 的 变 量 的 值 调 用 类 中 其 他 方 法 public class Test { public void t() { this.t2(); public void t2() { System.out.println("t2 方 法 "); 作 为 方 法 名 来 初 始 化 对 象 this 用 在 构 造 方 法 中,this() 也 就 是 相 当 于 调 用 本 类 的 其 它 构 造 方 法, 它 必 须 作 为 构 造 方 法 的 第 一 句 示 例 如 下 : 第 79 页

80 public class Test { public Test() { this(3);// 在 这 里 调 用 本 类 的 另 外 的 构 造 方 法 public Test(int a) { public static void main(string[] args) { Test t = new Test(); 3.5 引 用 类 型 早 些 时 候 的 编 程 语 言 和 初 级 程 序 员 将 每 个 变 量 看 作 相 互 无 关 的 实 体 例 如, 如 果 一 个 程 序 需 处 理 某 个 日 期, 则 要 声 明 三 个 单 独 的 整 数 : int day, month, year; 上 述 语 句 作 了 两 件 事, 一 是 当 程 序 需 要 日 月 或 年 的 有 关 信 息 时, 它 将 操 作 一 个 整 数 ; 二 是 为 那 些 整 数 分 配 存 储 器 尽 管 这 种 作 法 很 容 易 理 解, 但 它 存 在 两 个 重 大 缺 陷 首 先, 如 果 程 序 需 同 时 记 录 几 个 日 期, 则 需 要 三 个 不 同 的 声 明 例 如, 要 记 录 两 个 生 日, 你 可 能 使 用 : int mybirthday, mybirthmonth, mybirthyear; int yourbirthday, yourbirthmonth, yourbirthyear; 这 种 方 法 很 快 就 会 引 起 混 乱, 因 为 需 要 的 名 称 很 多 第 二 个 缺 陷 是 这 种 方 法 忽 视 了 日 月 和 年 之 间 的 联 系 并 把 每 个 变 量 都 作 为 一 个 独 立 的 值, 每 个 变 量 都 是 一 个 独 立 单 元 为 了 解 决 这 个 问 题,Java 引 入 了 引 用 类 型, 允 许 程 序 员 自 己 定 义 类 型 什 么 是 引 用 类 型 引 用 类 型 (reference type) 指 向 一 个 对 象, 不 是 原 始 值, 指 向 对 象 的 变 量 是 引 用 变 量 在 Java 里 面 除 去 基 本 数 据 类 型 的 其 它 类 型 都 是 引 用 数 据 类 型, 自 己 定 义 的 class 类 都 是 引 用 类 型, 可 以 像 基 本 类 型 一 样 使 用 在 Java 程 序 运 行 时, 会 为 引 用 类 型 分 配 一 定 量 的 存 储 空 间 并 解 释 该 存 储 空 间 的 内 容 示 例 如 下 : public class MyDate { private int day = 8; private int month = 8; private int year = 2008; 第 80 页

81 public MyDate(int day, int month, int year){ public void print(){ public class TestMyDate { public static void main(string args[]) { // 这 个 today 变 量 就 是 一 个 引 用 类 型 的 变 量 MyDate today = new MyDate(23, 7, 2008); 引 用 类 型 的 赋 值 在 Java 编 程 语 言 中, 用 类 的 一 个 类 型 声 明 的 变 量 被 指 定 为 引 用 类 型, 这 是 因 为 它 正 在 引 用 一 个 非 原 始 类 型, 这 对 赋 值 具 有 重 要 的 意 义 请 看 下 列 代 码 片 段 : int x = 7; int y = x; String s = "Hello"; String t = s; 四 个 变 量 被 创 建 : 两 个 原 始 类 型 int 和 两 个 引 用 类 型 String x 的 值 是 7, 而 这 个 值 被 复 制 到 y;x 和 y 是 两 个 独 立 的 变 量 且 其 中 任 何 一 个 的 进 一 步 的 变 化 都 不 对 另 外 一 个 构 成 影 响 至 于 变 量 s 和 t, 只 有 一 个 String 对 象 存 在, 它 包 含 了 文 本 Hello,s 和 t 均 引 用 这 个 单 一 的 对 象 x y s t 7 7 0x1fb8ee3 0x1fb8ee3 Hello 将 变 量 t 重 新 定 义 为 :t= World ; 则 新 的 对 象 World 被 创 建, 而 t 引 用 这 个 对 象 上 述 过 程 被 描 述 如 下 : x y s t 7 7 0x1fb8ee3 0x1fb8f25 Hello World 按 值 传 递 还 是 按 引 用 传 递 这 个 在 Java 里 面 是 经 常 被 提 起 的 问 题, 也 有 一 些 争 论, 似 乎 最 后 还 有 一 个 所 谓 的 结 论 : 在 Java 里 面 参 数 传 递 都 是 按 值 传 递 事 实 上, 这 很 容 易 让 人 迷 惑, 下 面 先 分 别 看 看 什 么 是 按 值 传 递, 什 么 是 按 引 用 传 递, 只 要 能 正 确 理 解, 至 于 称 作 按 什 么 传 递 就 不 是 个 大 问 题 了 第 81 页

82 按 值 传 递 指 的 是 在 方 法 调 用 时, 传 递 的 参 数 是 按 值 的 拷 贝 传 递 示 例 如 下 : 1. public class TempTest { 2. private void test1(int a) { 3. // 做 点 事 情 4. a++; public static void main(string[] args) { 7. TempTest t = new TempTest(); 8. int a = 3; 9. t.test1(a);// 这 里 传 递 的 参 数 a 就 是 按 值 传 递 10. System.out.println("main 方 法 中 的 a===" + a); 按 值 传 递 重 要 特 点 : 传 递 的 是 值 的 拷 贝, 也 就 是 说 传 递 后 就 互 不 相 关 了 第 9 行 的 a 和 第 2 行 的 a 是 两 个 变 量, 当 改 变 第 2 行 a 的 值, 第 9 行 a 的 值 是 不 变 的, 所 以 打 印 结 果 是 3 main: a test1:a 3 4 我 们 把 第 9 行 的 a 称 之 为 实 参, 第 2 行 的 a 称 之 为 形 参 ; 对 于 基 本 数 据 类 型, 形 参 数 据 的 改 变, 不 影 响 实 参 的 数 据 按 引 用 传 递 指 的 是 在 方 法 调 用 时, 传 递 的 参 数 是 按 引 用 进 行 传 递, 其 实 传 递 的 引 用 的 地 址, 也 就 是 变 量 所 对 应 的 内 存 空 间 的 地 址 示 例 如 下 : 1. public class TempTest { 2. private void test1(a a) { 3. a.age = 20; 4. System.out.println("test1 方 法 中 的 age="+a.age); public static void main(string[] args) { 7. TempTest t = new TempTest(); 8. A a = new A(); 9. a.age = 10; 10. t.test1(a); // 这 里 传 递 的 参 数 a 就 是 按 引 用 传 递 11. System.out.println("main 方 法 中 的 age="+a.age); class A { 15. public int age = 0; 16. 运 行 结 果 如 下 : test1 方 法 中 的 age=20 main 方 法 中 的 age=20 第 82 页

83 按 引 用 传 递 的 重 要 特 点 : 传 递 的 是 值 的 引 用, 也 就 是 说 传 递 前 和 传 递 后 都 指 向 同 一 个 引 用 ( 也 就 是 同 一 个 内 存 空 间 ) 要 想 正 确 理 解 按 引 用 传 递 的 过 程, 就 必 须 学 会 理 解 内 存 分 配 的 过 程, 内 存 分 配 示 意 图 可 以 辅 助 我 们 去 理 解 这 个 过 程 用 上 面 的 例 子 来 进 行 分 析 : (1) 运 行 开 始, 运 行 第 8 行, 创 建 了 一 个 A 的 实 例, 内 存 分 配 示 意 图 如 下 : main: a 3 0x1fb8ee age=0 这 是 一 个 A 的 实 例 (2) 运 行 第 9 行, 是 修 改 A 实 例 里 面 的 age 的 值, 运 行 后 内 存 分 配 示 意 图 如 下 : main:a 0x1fb8ee3 age=10 这 是 一 个 A 的 实 例 (3) 运 行 第 10 行, 是 把 main 方 法 中 的 变 量 a 所 引 用 的 内 存 空 间 地 址, 按 引 用 传 递 给 test1 方 法 中 的 a 变 量 请 注 意 : 这 两 个 a 变 量 是 完 全 不 同 的, 不 要 被 名 称 相 同 所 蒙 蔽, 但 它 们 指 向 了 同 一 个 A 实 例 内 存 分 配 示 意 图 如 下 : main:a test1:a 0x1fb8ee3 0x1fb8ee3 age=10 这 是 一 个 A 的 实 例 (4) 运 行 第 3 行, 为 test1 方 法 中 的 变 量 a 指 向 的 A 实 例 的 age 进 行 赋 值, 完 成 后 形 成 新 的 内 存 示 意 图 如 下 : main:a test1:a 0x1fb8ee3 0x1fb8ee3 age=20 这 是 一 个 A 的 实 例 此 时 A 实 例 的 age 值 的 变 化 是 由 test1 方 法 引 起 的 (5) 运 行 第 4 行, 根 据 此 时 的 内 存 示 意 图, 输 出 test1 方 法 中 的 age=20 (6) 运 行 第 11 行, 根 据 此 时 的 内 存 示 意 图, 输 出 main 方 法 中 的 age=20 第 83 页

84 对 上 述 例 子 的 改 变 理 解 了 上 面 的 例 子, 可 能 有 人 会 问, 那 么 能 不 能 让 按 照 引 用 传 递 的 值, 相 互 不 影 响 呢? 就 是 test1 方 法 里 面 的 修 改 不 影 响 到 main 方 法 里 面 呢? 新 加 的 : 方 法 是 在 test1 方 法 里 面 新 new 一 个 实 例 就 可 以 了 改 变 成 下 面 的 例 子, 其 中 第 3 行 为 1. public class TempTest { 2. private void test1(a a) { 3. a = new A();// 新 加 的 一 行 4. a.age = 20; 5. System.out.println("test1 方 法 中 的 age=" + a.age); public static void main(string[] args) { 8. TempTest t = new TempTest(); 9. A a = new A(); 10. age = 10; 11. t.test1(a); 12. System.out.println("main 方 法 中 的 age=" + a.age); class A { 16. public int age = 0; 17. 运 行 结 果 为 : test1 方 法 中 的 age=20 main 方 法 中 的 age=10 为 什 么 这 次 的 运 行 结 果 和 前 面 的 例 子 不 一 样 呢, 还 是 使 用 内 存 示 意 图 来 理 解 一 下 : (1) 运 行 开 始, 运 行 第 9 行, 创 建 了 一 个 A 的 实 例, 内 存 分 配 示 意 图 如 下 : 0x1fb8ee3 main:a age=0 这 是 一 个 第 9 行 (2) 运 行 第 10 行, 是 修 改 A 实 例 里 面 的 age 的 值, 运 行 后 内 存 分 配 示 意 图 如 下 : 创 建 的 A 实 例 0x1fb8ee3 main:a age=10 这 是 一 个 第 9 行 创 建 的 A 实 例 (3) 运 行 第 11 行, 是 把 main 方 法 中 的 变 量 a 所 引 用 的 内 存 空 间 地 址, 按 引 用 传 递 给 test1 方 法 中 的 a 变 量 请 注 意 : 这 两 个 a 变 量 是 完 全 不 同 的, 不 要 被 名 称 相 同 所 蒙 蔽 main:a 0x1fb8ee3 age=10 这 是 一 个 第 9 行 test1:a 0x1fb8ee3 也 就 是 说 : 是 两 个 变 量 都 指 向 同 一 个 空 间 创 建 的 A 实 例 第 84 页

85 (4) 运 行 第 3 行, 为 test1 方 法 中 的 变 量 a 重 新 生 成 了 新 的 A 实 例 的, 完 成 后 形 成 的 新 的 内 存 示 意 图 如 下 : main:a 0x1fb8ee3 test1:a 0x1fb81f3 age=10 这 是 一 个 第 9 行 创 建 的 A 实 例 age=0 这 是 一 个 第 3 行 创 建 的 A 实 例 (5) 运 行 第 4 行, 为 test1 方 法 中 的 变 量 a 指 向 的 新 的 A 实 例 的 age 进 行 赋 值, 完 成 后 形 成 的 新 的 内 存 示 意 图 如 下 : main:a 0x1fb8ee3 test1:a 0x1fb81f3 age=10 这 是 一 个 第 9 行 创 建 的 A 实 例 age=20 这 是 一 个 第 3 行 变 的 创 建 的 A 实 例 注 意 : 这 个 时 候 test1 方 法 中 的 变 量 a 的 age 被 改 变, 而 main 方 法 中 的 是 没 有 改 (6) 运 行 第 5 行, 根 据 此 时 的 内 存 示 意 图, 输 出 test1 方 法 中 的 age=20 (7) 运 行 第 12 行, 根 据 此 时 的 内 存 示 意 图, 输 出 main 方 法 中 的 age=10 说 明 : 在 Java 里 面 参 数 传 递 都 是 按 值 传 递 这 句 话 的 意 思 是 : 按 值 传 递 是 传 递 的 值 的 拷 贝, 按 引 用 传 递 其 实 传 递 的 是 引 用 的 地 址 值, 所 以 统 称 按 值 传 递 在 Java 里 面 只 有 基 本 类 型 和 按 照 下 面 这 种 定 义 方 式 的 String 是 按 值 传 递, 其 它 的 都 是 按 引 用 传 递 就 是 直 接 使 用 双 引 号 定 义 字 符 串 方 式 :String str = "Java 快 车 "; 3.6 类 中 的 变 量 实 例 变 量 和 局 部 变 量 在 方 法 外 定 义 的 变 量 主 要 是 实 例 变 量, 它 们 是 在 使 用 new Xxxx () 创 建 一 个 对 象 时 被 分 配 内 存 空 间 的 每 当 创 建 一 个 对 象 时, 系 统 就 为 该 类 的 所 有 实 例 变 量 分 配 存 储 空 间 ; 创 建 多 个 对 象 就 有 多 份 实 例 变 量 通 过 对 象 的 引 用 就 可 以 访 问 实 例 变 量 第 85 页

86 在 方 法 内 定 义 的 变 量 或 方 法 的 参 数 被 称 为 局 部 (local) 变 量, 有 时 也 被 用 为 自 动 (automatic) 临 时 (temporary) 或 栈 (stack) 变 量 方 法 参 数 变 量 定 义 在 一 个 方 法 调 用 中 传 送 的 自 变 量, 每 次 当 方 法 被 调 用 时, 一 个 新 的 变 量 就 被 创 建 并 且 一 直 存 在 到 程 序 的 运 行 跳 离 了 该 方 法 当 执 行 进 入 一 个 方 法 遇 到 局 部 变 量 的 声 明 语 句 时, 局 部 变 量 被 创 建, 当 执 行 离 开 该 方 法 时, 局 部 变 量 被 取 消, 也 就 是 该 方 法 结 束 时 局 部 变 量 的 生 命 周 期 也 就 结 束 了 因 而, 局 部 变 量 有 时 也 被 引 用 为 临 时 或 自 动 变 量 在 成 员 方 法 内 定 义 的 变 量 对 该 成 员 变 量 是 局 部 的, 因 而, 你 可 以 在 几 个 成 员 方 法 中 使 用 相 同 的 变 量 名 而 代 表 不 同 的 变 量 该 方 法 的 应 用 如 下 所 示 : public class Test { private int i; // Test 类 的 实 例 变 量 public int firstmethod() { int j = 1; // 局 部 变 量 // 这 里 能 够 访 问 i 和 j System.out.println("firstMethod 中 i=" + i + ",j=" + j); return 1; // firstmethod() 方 法 结 束 public int secondmethod(float f) { // method parameter int j = 2; // 局 部 变 量, 跟 firstmethod() 方 法 中 的 j 是 不 同 的 // 这 个 j 的 范 围 是 限 制 在 secondmethod() 方 法 中 的 // 在 这 个 地 方, 可 以 同 时 访 问 i,j,f System.out.println("secondMethod 中 i=" + i + ",j=" + j + ",f=" +f); return 2; public static void main(string[] args) { Test t = new Test(); t.firstmethod(); t.secondmethod(3); 实 例 变 量 的 初 始 化 在 Java 程 序 中, 任 何 变 量 都 必 须 经 初 始 化 后 才 能 被 使 用 当 一 个 对 象 被 创 建 时, 实 例 变 量 在 分 配 内 存 空 间 时 按 程 序 员 指 定 的 初 始 化 值 赋 值, 否 则 系 统 将 按 下 列 默 认 值 进 行 初 始 化 : 数 据 类 型 初 始 值 byte 0 short 0 int 0 long 0L char '\u0000' 第 86 页

87 float 0.0F double 0.0D boolean false 所 有 引 用 类 型 null 注 意 : 一 个 具 有 空 值 null 的 引 用 不 引 用 任 何 对 象 试 图 使 用 它 引 用 的 对 象 将 会 引 起 一 个 异 常 异 常 是 出 现 在 运 行 时 的 错 误, 这 将 在 模 块 异 常 中 讨 论 在 方 法 外 定 义 的 变 量 被 自 动 初 始 化 局 部 变 量 必 须 在 使 用 之 前 做 手 工 ( 由 程 序 员 进 行 ) 初 始 化 如 果 编 译 器 能 够 确 认 一 个 变 量 在 初 始 化 之 前 可 能 被 使 用 的 情 形, 编 译 器 将 报 错 public class Test { private int i; // Test 类 的 实 例 变 量 public void test1() { int x = (int) (Math.random() * 100); int y; int z; if (x > 50) { y = 9; z = y + x; // 将 会 引 起 错 误, 因 为 y 可 能 还 没 有 被 初 始 化 就 使 用 了 public static void main(string[] args) { Test t = new Test(); t.test1(); 3.7 Java 类 的 基 本 运 行 顺 序 作 为 程 序 员, 应 该 对 自 己 写 的 程 序 具 备 充 分 的 掌 控 能 力, 应 该 清 楚 程 序 的 基 本 运 行 过 程, 否 则 糊 里 糊 涂 的, 不 利 于 对 程 序 的 理 解 和 控 制, 也 不 利 于 技 术 上 的 发 展 我 们 以 下 面 的 类 来 说 明 一 个 基 本 的 Java 类 的 运 行 顺 序 : 1. public class Test { 2. private String name; 3. private int age; public Test() { 6. name = "Tom"; 7. age = 20; public static void main(string[] args) { 10. Test t = new Test(); 11. System.out.println(t.name + " 的 年 龄 是 " + t.age ); 第 87 页

88 运 行 的 基 本 顺 序 是 : (1) 先 运 行 到 第 9 行, 这 是 程 序 的 入 口 (2) 然 后 运 行 到 第 10 行, 这 里 要 new 一 个 Test, 就 要 调 用 Test 的 构 造 方 法 (3) 就 运 行 到 第 5 行, 注 意 : 可 能 很 多 人 觉 得 接 下 来 就 应 该 运 行 第 6 行 了, 错! 初 始 化 一 个 对 象, 必 须 先 初 始 化 它 的 属 性 (4) 因 此 运 行 到 第 2 行, 然 后 是 第 3 行 (5) 属 性 初 始 化 完 过 后, 才 回 到 构 造 方 法, 执 行 里 面 的 代 码, 也 就 是 第 6 行 第 7 行 (6) 然 后 是 第 8 行, 表 示 new 一 个 Test 实 例 完 成 (7) 然 后 回 到 main 方 法 中 执 行 第 11 行 (8) 然 后 是 第 12 行,main 方 法 执 行 完 毕 说 明 : 这 里 只 是 说 明 一 个 基 本 的 运 行 过 程, 没 有 考 虑 更 多 复 杂 的 情 况 第 88 页

89 3.8 学 习 目 标 1. 理 解 为 什 么 要 面 向 对 象, 理 解 现 实 中 的 对 象 和 类 型 与 Java 中 的 类 和 对 象 的 相 互 关 系 2. 能 够 描 述 Java 中 类 的 6 个 组 成 部 分 3. 简 述 什 么 是 包? 包 的 功 能, 描 述 使 用 包 的 好 处 4. 了 解 Java 中 的 常 见 包, 能 够 写 出 5 个 以 上 的 JDK 中 的 包, 以 及 他 们 的 基 本 功 能 5. 能 够 描 述 import 关 键 字 的 用 法 6. 简 述 Java 的 访 问 修 饰 符 类 型? 分 别 有 什 么 功 能? 7. 能 够 描 述 类 定 义 的 完 整 的 语 法 结 构 8. 能 够 描 述 属 性 定 义 的 完 整 的 语 法 结 构 9. 能 够 描 述 构 造 方 法 定 义 的 完 整 的 语 法 结 构 10. 理 解 构 造 方 法 的 调 用 和 系 统 提 供 的 默 认 的 构 造 方 法 11. 理 解 析 构 方 法 12. 能 够 描 述 方 法 定 义 的 完 整 的 语 法 结 构 13. 分 别 说 明 : 在 类 上 在 属 性 上 在 方 法 上 等 能 使 用 那 些 访 问 修 饰 符 14. 什 么 是 形 参 ( 形 式 参 数 )? 什 么 是 实 参 ( 实 际 参 数 )? 15. 如 何 通 过 类 创 建 对 象, 如 何 调 用 对 象 的 方 法, 如 何 调 用 对 象 的 属 性 16. 什 么 是 引 用 数 据 类 型? 17. 什 么 是 按 值 传 递, 什 么 是 按 引 用 传 递? 18. this 关 键 字 的 用 法? 19. 什 么 时 候 使 用 this 关 键 字? 20. 什 么 是 实 例 变 量, 什 么 是 局 部 变 量? 21. 如 何 理 解 属 性 的 初 始 化? 22. 什 么 是 强 制 类 型 转 换 23. 简 述 Java 类 的 基 本 运 行 顺 序 第 89 页

90 3.9 练 习 1. 请 编 写 一 个 方 法 实 现 如 下 功 能 : 将 0 至 6 的 数 字 转 换 为 星 期 日 到 星 期 六 的 字 符 串 要 求 : 输 入 一 个 数 字 参 数, 返 回 字 符 串 2. 请 编 写 一 个 方 法 实 现 如 下 功 能 : 将 任 意 三 个 整 数 a,b,c 按 从 小 到 大 排 序 要 求 : 输 入 三 个 参 数, 返 回 一 个 排 好 顺 序 的 字 符 串 3. 请 编 写 一 个 方 法 实 现 如 下 功 能 : 计 算 1 加 到 n(n>=2 的 整 数 ) 的 总 和 4. 请 编 写 一 个 方 法 实 现 如 下 功 能 : 得 到 一 个 整 数 的 绝 对 值 5. 请 编 写 一 个 方 法, 输 入 两 个 参 数, 判 断 第 一 个 数 字 是 否 是 第 二 个 数 字 的 整 数 倍 数, 如 果 是, 返 回 true; 如 果 不 是, 返 回 false 6. 请 编 写 一 个 方 法, 输 入 正 方 形 的 边 长, 然 后 利 用 星 号 和 空 格, 打 印 具 有 那 个 边 长 的 一 个 空 心 正 方 形 假 定 输 入 参 数 是 5, 则 输 出 效 果 应 该 是 下 面 这 样 : 7. 回 文 是 一 种 特 殊 的 数 字 或 文 字 短 语, 无 论 顺 读, 还 是 倒 读, 结 果 都 是 一 样 的 例 如, 下 面 这 些 整 数 其 实 都 是 回 文 : 编 写 一 个 方 法 判 断 是 否 是 回 文 : 输 入 数 字, 如 果 是 回 文, 返 回 true, 否 则 返 回 false 8. 请 编 写 一 个 方 法 实 现 如 下 功 能 : 输 入 三 个 非 零 的 整 数 值, 判 断 它 们 是 否 能 代 表 一 个 三 角 形 的 3 个 边 长, 如 果 能, 返 回 true; 如 果 不 能 返 回 false ( 提 示 : 判 断 三 个 边 长 能 否 组 成 三 角 形 的 规 则 是 : 任 意 两 个 边 长 之 和 大 于 第 三 个 边 长 ) 9. 请 编 写 一 个 方 法 实 现 如 下 功 能 : 用 程 序 找 出 每 位 数 的 立 方 和 等 于 该 数 本 身 值 的 所 有 的 3 位 数 ( 水 仙 花 数 ) 10. 有 一 个 序 列, 首 两 项 为 0,1, 以 后 各 项 值 为 前 两 项 值 之 和 写 一 个 方 法 来 实 现 求 这 个 序 列 的 和 11. 写 一 个 MyPoint 完 全 封 装 类, 其 中 含 有 私 有 的 int 类 型 的 x 和 y 属 性, 分 别 用 公 有 的 getx 和 setx gety 和 sety 方 法 访 问, 定 义 一 个 tostring 方 法 用 来 显 示 这 个 对 象 的 x y 的 值, 如 显 示 (1,2), 最 后 用 main 方 法 测 试 12. 为 MyPoint 类 添 加 public boolean equals(mypoint mp) 方 法, 创 建 两 个 MyPoint 对 象, 使 用 equals 方 法 比 较 两 个 对 象 是 否 相 等, 再 使 用 == 比 较 两 个 对 象 是 否 相 等, 思 考 两 种 比 较 的 不 同 之 处 第 90 页

91 4 Java 高 级 类 特 性 面 向 对 象 有 三 大 特 征, 即 封 装 继 承 多 态 4.1 封 装 封 装 这 个 词 听 起 来 好 象 是 将 什 么 东 西 包 裹 起 来 不 要 别 人 看 见 一 样, 就 好 象 是 把 东 西 装 进 箱 子 里 面, 这 样 别 人 就 不 知 道 箱 子 里 面 装 的 是 什 么 东 西 了 其 实 JAVA 中 的 封 装 这 个 概 念 也 就 和 这 个 是 差 不 多 的 意 思 封 装 是 JAVA 面 向 对 象 的 特 点 的 表 现, 封 装 是 一 种 信 息 隐 蔽 技 术 它 有 两 个 含 义 : 即 把 对 象 的 全 部 属 性 和 全 部 服 务 结 合 在 一 起, 形 成 一 个 不 可 分 割 的 独 立 单 位 ; 以 及 尽 可 能 隐 藏 对 象 的 内 部 结 构 也 就 是 说, 如 果 我 们 使 用 了 封 装 技 术 的 话, 别 人 就 只 能 用 我 们 做 出 来 的 东 西 而 看 不 见 我 们 做 的 这 个 东 西 的 内 部 结 构 了 封 装 的 功 能 : - 迫 使 用 户 去 使 用 一 个 界 面 访 问 数 据 - 使 代 码 更 好 维 护 - 隐 藏 对 象 的 实 现 细 节 封 装 迫 使 用 户 通 过 方 法 访 问 数 据 能 保 护 对 象 的 数 据 不 被 误 修 改, 还 能 使 对 象 的 重 用 变 得 更 简 单 数 据 隐 藏 通 常 指 的 就 是 封 装 它 将 对 象 的 外 部 界 面 与 对 象 的 实 现 区 分 开 来, 隐 藏 实 现 细 节 迫 使 用 户 去 使 用 外 部 界 面, 即 使 实 现 细 节 改 变, 还 可 通 过 界 面 承 担 其 功 能 而 保 留 原 样, 确 保 调 用 它 的 代 码 还 继 续 工 作 封 装 使 代 码 维 护 更 简 单 4.2 继 承 继 承 在 面 向 对 象 世 界 里 面, 常 常 要 创 建 某 对 象 ( 如 : 一 个 职 员 对 象 ), 然 后 需 要 一 个 该 基 本 对 象 的 更 专 业 化 的 版 本, 比 如, 可 能 需 要 一 个 经 理 的 对 象 显 然 经 理 实 际 上 是 一 个 职 员, 经 理 和 职 员 具 有 is-a 的 关 系, 经 理 只 是 一 个 带 有 附 加 特 征 的 职 员 因 此, 需 要 有 一 种 办 法 从 现 有 对 象 来 创 建 一 个 新 对 象, 这 个 方 式 就 是 继 承 现 实 中 的 事 务, 只 要 具 有 is-a 的 关 系, 在 java 中 都 可 以 用 继 承 表 示 继 承 是 面 向 对 象 软 件 技 术 当 中 的 一 个 概 念 如 果 一 个 对 象 A 继 承 自 另 一 个 对 象 B, 就 把 这 个 A 称 为 B 的 子 对 象, 而 把 B 称 为 A 的 父 对 象 继 承 可 以 使 得 子 对 象 具 有 父 对 象 的 各 种 属 性 和 方 法, 而 不 需 要 再 次 编 写 相 同 的 代 码 在 令 子 对 象 继 承 父 对 象 的 同 时, 可 以 重 新 定 义 某 些 属 性, 并 重 写 某 些 方 法, 即 覆 盖 父 对 象 的 原 有 属 性 和 方 法, 使 其 获 得 与 父 对 象 不 同 的 功 能 第 91 页

92 4.2.2 extends 关 键 字 在 Java 中 使 用 extends 关 键 字 来 表 达 继 承 的 关 系, 比 如 : 经 理 这 个 类 继 承 雇 员 这 个 类, 示 例 如 下 : public class Employee { String name; Date hiredate; Date dateofbirth; String jobtitle; int grade;... public class Manager extends Employee { String department; Employee[] subordinates;... 在 这 样 的 定 义 中,Manager 类 被 定 义, 具 有 Employee 所 拥 有 的 所 有 变 量 及 方 法 所 有 这 些 变 量 和 方 法 都 是 从 父 类 的 定 义 中 继 承 来 的 所 有 的 程 序 员 需 要 做 的 是 定 义 额 外 特 征 或 规 定 将 适 用 的 变 化 注 意 : 这 种 方 法 是 在 维 护 和 可 靠 性 方 面 的 一 个 伟 大 进 步 如 果 在 Employee 类 中 进 行 修 改, 那 么,Manager 类 就 会 自 动 修 改, 而 不 需 要 程 序 员 做 任 何 工 作, 除 了 对 它 进 行 编 译 父 子 类 的 初 始 化 顺 序 Java 技 术 安 全 模 式 要 求 在 子 类 执 行 任 何 东 西 之 前, 描 述 父 类 的 一 个 对 象 的 各 个 方 面 都 必 须 初 始 化 因 此,Java 编 程 语 言 总 是 在 执 行 子 构 造 方 法 前 调 用 父 类 构 造 方 法 的 版 本 有 继 承 的 类 在 运 行 的 时 候, 一 定 要 记 得 : 初 始 化 子 类 必 先 初 始 化 父 类, 这 是 Java 程 序 的 一 个 基 本 运 行 过 程 比 如 : public class Test extends Parent { private String name; private int age; public Test() { name="tom"; age=20; public static void main(string[] args) { Test t = new Test(); System.out.println(t.name + " 的 年 龄 是 " + t.age); class Parent { 第 92 页

93 private int num = 1; public Parent() { System.out.println(" 现 在 初 始 化 父 类 "); public void test() { System.out.println(" 这 是 父 类 的 test 方 法 "); 上 述 类 的 基 本 运 行 顺 序 是 : (1) 先 运 行 到 第 8 行, 这 是 程 序 的 入 口 (2) 然 后 运 行 到 第 9 行, 这 里 要 new 一 个 Test, 就 要 调 用 Test 的 构 造 方 法 (3) 就 运 行 到 第 4 行, 注 意 : 初 始 化 子 类 必 先 初 始 化 父 类 (4) 要 先 初 始 化 父 类, 所 以 运 行 到 第 15 行 (5) 然 后 是 第 14 行, 初 始 化 一 个 类, 必 须 先 初 始 化 它 的 属 性 (6) 然 后 是 第 16 行 (7) 然 后 是 第 17 行, 表 示 父 类 初 始 化 完 成 (8) 然 后 是 回 到 子 类, 开 始 初 始 化 属 性, 因 此 运 行 到 第 2 行, 然 后 是 第 3 行 (9) 子 类 属 性 初 始 化 完 过 后, 才 回 到 子 类 的 构 造 方 法, 执 行 里 面 的 代 码, 也 就 是 第 5 6 行 (10) 然 后 是 第 7 行, 表 示 new 一 个 Test 实 例 完 成 (11) 然 后 回 到 main 方 法 中 执 行 第 10 行 (12) 然 后 是 第 11 行 单 继 承 性 单 继 承 性 : 当 一 个 类 从 一 个 唯 一 的 类 继 承 时, 被 称 做 单 继 承 性 单 继 承 性 使 代 码 更 可 靠 接 口 提 供 多 继 承 性 的 好 处, 而 且 没 有 ( 多 继 承 的 ) 缺 点 Java 编 程 语 言 允 许 一 个 类 仅 能 继 承 一 个 其 它 类, 即 一 个 类 只 能 有 一 个 父 类 这 个 限 制 被 称 做 单 继 承 性 单 继 承 性 与 多 继 承 性 的 优 点 是 面 向 对 象 程 序 员 之 间 广 泛 讨 论 的 话 题 Java 编 程 语 言 加 强 了 单 继 承 性 限 制 而 使 代 码 更 为 可 靠, 尽 管 这 样 有 时 会 增 加 程 序 员 的 工 作 后 面 会 学 到 一 个 被 叫 做 接 口 (interface) 的 语 言 特 征, 它 允 许 多 继 承 性 的 大 部 分 好 处, 而 不 受 其 缺 点 的 影 响 使 用 继 承 性 的 子 类 的 一 个 例 子 如 图 所 示 : 第 93 页

94 4.2.5 构 造 方 法 不 能 被 继 承 尽 管 一 个 子 类 从 父 类 继 承 所 有 的 方 法 和 变 量, 但 它 不 继 承 构 造 方 法, 掌 握 这 一 点 很 重 要 一 个 类 能 得 到 构 造 方 法, 只 有 两 个 办 法 或 者 写 构 造 方 法, 或 者 根 本 没 有 写 构 造 方 法, 类 有 一 个 默 认 的 构 造 方 法 4.3 方 法 的 覆 盖 和 重 载 方 法 的 覆 盖 什 么 是 方 法 的 覆 盖 (Overridden Methods) 在 类 继 承 中, 子 类 可 以 修 改 从 父 类 继 承 来 的 行 为, 也 就 是 说 子 类 能 创 建 一 个 与 父 类 方 法 有 不 同 功 能 的 方 法, 但 具 有 相 同 的 : 名 称 返 回 类 型 参 数 列 表 如 果 在 子 类 中 定 义 一 个 方 法, 其 方 法 名 称 返 回 值 类 型 及 参 数 列 表 正 好 与 父 类 中 方 法 的 名 称 返 回 值 类 型 及 参 数 列 表 相 匹 配, 那 么 称, 子 类 的 方 法 覆 盖 了 父 类 的 方 法 示 例 如 下 在 Employee 和 Manager 类 中 的 这 些 方 法 : public class Employee { String name; int salary; public String getdetails() { return " Name: " + name + " \n " + "Salary: " + salary; public class Manager extends Employee { String department; public String getdetails() { return " Name: " + name + " \n " + " Manager of " + department; Manager 类 有 一 个 定 义 的 getdetails() 方 法, 因 为 它 是 从 Employee 类 中 继 承 的 基 本 的 方 法 被 子 类 的 版 本 所 代 替 或 覆 盖 了 方 法 的 覆 盖 规 则 子 类 的 方 法 的 名 称 以 及 子 类 方 法 参 数 的 顺 序 必 须 与 父 类 中 的 方 法 的 名 称 以 及 参 数 的 顺 序 相 同, 以 便 该 方 法 覆 盖 父 类 版 本 下 述 规 则 适 用 于 覆 盖 方 法 : 覆 盖 方 法 不 能 比 它 所 覆 盖 的 方 法 访 问 性 差 ( 即 访 问 权 限 不 允 许 缩 小 ) 第 94 页

95 覆 盖 方 法 不 能 比 它 所 覆 盖 的 方 法 抛 出 更 多 的 异 常 效 方 案 : 这 些 规 则 源 自 多 态 性 的 属 性 和 Java 编 程 语 言 必 须 保 证 类 型 安 全 的 需 要 考 虑 一 下 这 个 无 public class Parent { public void method() { public class Child extends Parent { private void method() {// 编 译 就 会 出 错 public class Test { public void othermethod() { Parent p1 = new Parent(); Parent p2 = new Child(); p1.method(); p2.method(); Java 编 程 语 言 语 义 规 定,p2.method() 导 致 方 法 的 Child 版 本 被 执 行, 但 因 为 方 法 被 声 明 为 private,p2( 声 明 为 Parent) 不 能 访 问 它 于 是, 语 言 语 义 冲 突 方 法 的 重 载 假 如 你 必 须 在 不 同 情 况 下 发 送 不 同 的 信 息 给 同 一 个 成 员 方 法 的 话, 该 怎 么 办 呢? 你 可 以 通 过 对 此 成 员 方 法 说 明 多 个 版 本 的 方 法 来 实 现 重 载 重 载 的 本 质 是 创 建 了 一 个 新 的 成 员 方 法 : 你 只 需 给 它 一 个 不 同 的 参 数 列 表 什 么 是 重 载 做 重 载 在 同 一 个 Java 类 中 ( 包 含 父 类 ), 如 果 出 现 了 方 法 名 称 相 同, 而 参 数 列 表 不 同 的 情 况 就 叫 参 数 列 表 不 同 的 情 况 包 括 : 个 数 不 同 类 型 不 同 顺 序 不 同 等 等 特 别 提 示, 仅 仅 参 数 变 量 名 称 不 同 是 不 可 以 的 示 例 如 下 例 所 示 : void getarea(int w,int h); void getarea(float w,float h); 在 第 二 种 情 况 下, 成 员 方 法 getarea() 接 受 两 个 浮 点 变 量 作 为 它 的 参 数, 编 译 器 根 据 调 用 时 的 不 同 参 数 来 决 定 该 调 用 哪 一 种 成 员 方 法, 假 如 你 把 两 个 整 数 提 供 给 成 员 方 法, 就 调 用 第 一 个 成 员 方 法 ; 假 如 你 把 两 个 浮 点 数 提 供 给 成 员 方 法, 第 二 个 成 员 方 法 就 被 调 用 第 95 页

96 法 当 写 代 码 来 调 用 这 些 方 法 中 的 一 个 方 法 时, 便 以 其 会 根 据 提 供 的 参 数 的 类 型 来 选 择 合 适 的 方 注 意 : 跟 成 员 方 法 一 样, 构 造 方 法 也 可 以 重 载 方 法 的 重 载 规 则 方 法 名 称 必 须 相 同 参 数 列 表 必 须 不 同 ( 个 数 不 同, 或 类 型 不 同, 或 参 数 排 列 顺 序 不 同 ) 方 法 的 返 回 类 型 可 以 相 同 也 可 以 不 相 同 仅 仅 返 回 类 型 不 同 不 足 以 成 为 方 法 的 重 载 注 意 : 调 用 语 句 的 参 数 表 必 须 有 足 够 的 不 同, 以 至 于 允 许 区 分 出 正 确 的 方 法 被 调 用 正 常 的 拓 展 晋 升 ( 如, 单 精 度 类 型 float 到 双 精 度 类 型 double) 可 能 被 应 用, 但 是 这 样 会 导 致 在 某 些 条 件 下 的 混 淆 比 较 方 法 的 覆 盖 和 重 载 重 载 方 法 : 在 一 个 类 ( 或 父 子 类 ) 中 用 相 同 的 名 字 创 建 多 个 方 法 ( 每 个 方 法 的 参 数 表 不 同 ) 方 法 覆 盖 : 在 一 个 类 中 创 建 的 方 法 与 父 类 中 方 法 的 名 字 返 回 类 型 和 参 数 表 相 同, 覆 盖 是 针 对 两 个 类 说 的, 而 且 必 须 是 子 类 ( 或 孙 类, 孙 孙 类 等 ) 覆 盖 掉 父 类 的 方 法 4.4 关 键 字 super 关 键 字 super 可 被 用 来 引 用 该 类 的 父 类, 它 被 用 来 引 用 父 类 的 成 员 变 量 或 方 法 父 类 行 为 被 调 用, 就 好 象 该 行 为 是 本 类 的 行 为 一 样, 而 且 调 用 行 为 不 必 发 生 在 父 类 中, 它 能 自 动 向 上 层 类 追 溯 super 关 键 字 的 功 能 : 点 取 父 类 中 被 子 类 隐 藏 了 的 数 据 成 员 点 取 已 经 覆 盖 了 的 方 法 作 为 方 法 名 表 示 父 类 构 造 方 法 点 取 父 类 中 被 子 类 隐 藏 了 的 数 据 成 员 或 方 法 public class Employee { private String name; private int salary; public String getdetails() { return "Name: " + name + "\nsalary: " + salary; public class Manager extends Employee { private String department; public String getdetails() { return super.getdetails() + // 调 用 父 类 的 方 法 第 96 页

97 "\ndepartment: " + department; 请 注 意,super.method() 格 式 的 调 用, 如 果 对 象 已 经 具 有 父 类 类 型, 那 么 它 的 方 法 的 整 个 行 为 都 将 被 调 用, 也 包 括 其 所 有 负 面 效 果 该 方 法 不 必 在 父 类 中 定 义, 它 也 可 以 从 某 些 祖 先 类 中 继 承 也 就 是 说 可 以 从 父 类 的 父 类 去 获 取, 具 有 追 溯 性, 一 直 向 上 去 找, 直 到 找 到 为 止, 这 是 一 个 很 重 要 的 特 点 调 用 父 类 构 造 方 法 在 许 多 情 况 下, 使 用 默 认 构 造 方 法 来 对 父 类 对 象 进 行 初 始 化 当 然 也 可 以 使 用 super 来 显 示 调 用 父 类 的 构 造 方 法 public class Employee { String name; public Employee(String n) { name = n; public class Manager extends Employee { String department; public Manager(String s, String d) { super(s); department = d; 注 意 : 无 论 是 super 还 是 this, 都 必 须 放 在 构 造 方 法 的 第 一 行 通 常 要 定 义 一 个 带 参 数 的 构 造 方 法, 并 要 使 用 这 些 参 数 来 控 制 一 个 对 象 的 父 类 部 分 的 构 造 可 能 通 过 从 子 类 构 造 方 法 的 第 一 行 调 用 关 键 字 super 的 手 段 调 用 一 个 特 殊 的 父 类 构 造 方 法 作 为 子 类 初 始 化 的 一 部 分 要 控 制 具 体 的 构 造 方 法 的 调 用, 必 须 给 super() 提 供 合 适 的 参 数 当 不 调 用 带 参 数 的 super 时, 缺 省 的 父 类 构 造 方 法 ( 即, 不 带 参 数 的 构 造 方 法 ) 被 隐 含 地 调 用 在 这 种 情 况 下, 如 果 没 有 缺 省 的 父 类 构 造 方 法, 将 导 致 编 译 错 误 public class Employee { String name; public Employee(String n) { name = n; public class Manager extends Employee { String department; public Manager(String s, String d) { super(s); // 调 用 父 类 参 数 为 String 类 型 的 构 造 方 法, 没 有 这 句 话, 编 译 会 出 错 department = d; 第 97 页

98 当 被 使 用 时,super 或 this 必 须 被 放 在 构 造 方 法 的 第 一 行 显 然, 两 者 不 能 被 放 在 一 个 单 独 行 中, 但 这 种 情 况 事 实 上 不 是 一 个 问 题 如 果 写 一 个 构 造 方 法, 它 既 没 有 调 用 super( ) 也 没 有 调 用 this( ), 编 译 器 自 动 插 入 一 个 调 用 到 父 类 构 造 方 法 中, 而 不 带 参 数 其 它 构 造 方 法 也 能 调 用 super( ) 或 this( ), 调 用 一 个 static 方 法 和 构 造 方 法 的 数 据 链 最 终 发 生 的 是 父 类 构 造 方 法 ( 可 能 几 个 ) 将 在 链 中 的 任 何 子 类 构 造 方 法 前 执 行 4.5 多 态 性 什 么 是 多 态 多 态 是 同 一 个 行 为 具 有 多 个 不 同 表 现 形 式 或 形 态 的 能 力 比 如 我 们 说 宠 物 这 个 对 象, 它 就 有 很 多 不 同 的 表 达 或 实 现, 比 如 有 小 猫 小 狗 蜥 蜴 等 等 那 么 我 到 宠 物 店 说 请 给 我 一 只 宠 物, 服 务 员 给 我 小 猫 小 狗 或 者 蜥 蜴 都 可 以, 我 们 就 说 宠 物 这 个 对 象 就 具 备 多 态 性 再 回 想 一 下 经 理 和 职 员 的 关 系, 经 理 类 具 有 父 类 职 员 类 的 所 有 属 性 成 员 和 方 法 这 就 是 说, 任 何 在 Employee 上 的 合 法 操 作 在 Manager 上 也 合 法 如 果 Employee 有 raisesalary() 和 fire() 两 个 方 法, 那 么 Manager 类 也 有 在 这 种 Manager 继 承 Employee 的 情 况 下, 一 个 Employee 既 可 以 是 一 个 普 通 的 Employee 类, 也 可 以 是 一 个 Manager 类 也 就 是 说 下 述 表 示 都 是 对 的 : Employee e = new Employee(); Employee e = new Manager(); 从 上 面 可 以 看 到 : 同 一 个 行 为 Employee 具 有 多 个 不 同 的 表 现 形 式 ( 既 可 以 是 一 个 普 通 的 Employee 类, 也 可 以 是 一 个 Manager 类 ), 这 就 被 称 为 多 态 注 意 : 方 法 没 有 多 态 的 说 法, 严 格 说 多 态 是 类 的 特 性 但 是 也 有 对 方 法 说 多 态 的, 了 解 一 下, 比 如 前 面 学 到 的 方 法 覆 盖 称 为 动 态 多 态, 是 一 个 运 行 时 问 题 ; 方 法 重 载 称 为 静 态 多 态, 是 一 个 编 译 时 问 题 多 态 与 类 型 一 个 对 象 只 有 一 个 格 式 ( 是 在 构 造 时 给 它 的 ) 但 是, 既 然 变 量 能 指 向 不 同 格 式 的 对 象, 那 么 变 量 就 是 多 态 性 的 也 就 是 说 一 个 对 象 只 有 一 种 形 式, 但 一 个 变 量 却 有 多 种 不 同 形 式 象 大 多 数 面 向 对 象 语 言 一 样,Java 实 际 上 允 许 父 类 类 型 的 引 用 变 量 指 向 一 个 子 类 的 对 象 因 此, 可 以 说 : Employee e = new Manager() 使 用 变 量 e 是 因 为, 你 能 访 问 的 对 象 部 分 只 是 Employee 的 一 个 部 分 ;Manager 的 特 殊 第 98 页

99 部 分 是 隐 藏 的 这 是 因 为 编 译 者 应 意 识 到,e 是 一 个 Employee, 而 不 是 一 个 Manager 因 而, 下 述 情 况 是 不 允 许 的 : e.department = " Finance " ; // 非 法 的, 编 译 时 会 出 错 可 能 有 的 人 会 不 理 解, 为 什 么 明 明 是 new 的 一 个 Manager, 却 不 能 访 问 Manager 的 属 性 数 据 原 因 在 于 编 译 的 时 候, 变 量 e 是 一 个 Employee 的 类 型, 编 译 器 并 不 去 管 运 行 时 e 指 向 的 具 体 对 象 是 一 个 Employee 的 对 象, 还 是 一 个 Manager 的 对 象, 所 以 它 只 能 访 问 到 Employee 里 面 定 义 的 属 性 和 方 法 所 以 说 编 译 时 看 数 据 类 型 那 么 要 想 访 问 到 Manager 里 面 的 department 该 怎 么 办 呢? 这 就 需 要 先 对 e 进 行 强 制 类 型 转 换, 把 它 还 原 成 为 Manager 类 型, 就 可 以 访 问 到 Manager 里 面 的 属 性 和 方 法 了, 如 下 : Employee e = new Manager(); Manager m = (Manager)e; m.department = " 开 发 部 "; // 这 就 是 合 法 的 了 到 底 运 行 哪 一 个 方 法? 这 里 会 给 我 们 带 来 一 个 麻 烦, 父 子 类 中 有 相 同 的 方 法, 那 么 在 运 行 时 到 底 调 用 哪 一 个 方 法 呢? 假 设 下 述 方 案 : Employee e = new Employee(); Manager m = new Manager(); 如 果 请 求 e.getdetails() 和 m.getdetails(), 就 会 调 用 不 同 的 行 为 Employee 对 象 将 执 行 与 Employee 有 关 的 getdetails 版 本, Manager 对 象 将 执 行 与 Manager 有 关 的 getdetails() 版 本 不 明 显 的 是 如 下 所 示 : Employee e = new Manager(); e.getdetails(); 或 某 些 相 似 效 果, 比 如 一 个 通 用 方 法 参 数 或 一 个 来 自 异 类 集 合 的 项 事 实 上, 你 得 到 与 变 量 的 运 行 时 类 型 ( 即, 变 量 所 引 用 的 对 象 的 类 型 ) 相 关 的 行 为, 而 不 是 与 变 量 的 编 译 时 类 型 相 关 的 行 为 这 是 面 向 对 象 语 言 的 一 个 重 要 特 征 它 也 是 多 态 性 的 一 个 特 征, 并 通 常 被 称 作 虚 拟 方 法 调 用 在 前 例 中, 被 执 行 的 e.getdetails() 方 法 来 自 对 象 的 真 实 类 型 Manager 因 此 规 则 是 : 编 译 时 看 数 据 类 型, 运 行 时 看 实 际 的 对 象 类 型 (new 操 作 符 后 跟 的 构 造 方 法 是 哪 个 类 的 ) 一 句 话 :new 谁 就 调 用 谁 的 方 法 instanceof 运 算 符 多 态 性 带 来 了 一 个 问 题 : 如 何 判 断 一 个 变 量 所 实 际 引 用 的 对 象 的 类 型 C++ 使 用 runtime-type information(rtti),java 使 用 instanceof 操 作 符 第 99 页

100 instanceof 运 算 符 功 能 : 用 来 判 断 某 个 实 例 变 量 是 否 属 于 某 种 类 的 类 型 一 旦 确 定 了 变 量 所 引 用 的 对 象 的 类 型 后, 可 以 将 对 象 恢 复 给 对 应 的 子 类 变 量, 以 获 取 对 象 的 完 整 功 能 示 例 如 下 : public class Employee extends Object{ public class Manager extends Employee { public class Contractor extends Employee{ 如 果 通 过 Employee 类 型 的 引 用 接 受 一 个 对 象, 它 变 不 变 成 Manager 或 Contractor 都 可 以 可 以 象 这 样 用 instanceof 来 测 试 : public void method(employee e) { if (e instanceof Manager) { // 如 果 雇 员 是 经 理, 可 以 做 的 事 情 写 在 这 里 else if (e instanceof Contractor) { // 如 果 雇 员 是 普 通 的 职 员, 可 以 做 的 事 情 写 在 这 里 else { // 说 明 是 临 时 雇 员, 可 以 做 的 事 情 写 在 这 里 多 态 对 象 的 类 型 转 换 在 你 接 收 父 类 的 一 个 引 用 时, 你 可 以 通 过 使 用 instanceof 运 算 符 判 定 该 对 象 实 际 上 是 你 所 要 的 子 类, 并 可 以 用 类 型 转 换 该 引 用 的 办 法 来 恢 复 对 象 的 全 部 功 能 public void method(employee e) { if (e instanceof Manager) { Manager m = (Manager)e; System.out.println(" This is the manager of " + m.department); // rest of operation 如 果 不 用 强 制 类 型 转 换, 那 么 引 用 e.department 的 尝 试 就 会 失 败, 因 为 编 译 器 不 能 将 被 称 做 department 的 成 员 定 位 在 Employee 类 中 如 果 不 用 instanceof 做 测 试, 就 会 有 类 型 转 换 失 败 的 危 险 通 常 情 况 下, 类 型 转 换 一 个 对 象 引 用 的 尝 试 是 要 经 过 几 种 检 查 的 : 向 上 强 制 类 型 转 换 类 层 次 总 是 允 许 的, 而 且 事 实 上 不 需 要 强 制 类 型 转 换 运 算 符 可 由 简 单 的 赋 值 实 现 严 格 讲 不 存 在 向 下 类 型 转 换, 其 实 就 是 强 制 类 型 转 换, 编 译 器 必 须 满 足 类 型 转 换 至 少 是 可 能 的 这 样 的 条 件 比 如, 任 何 将 Manager 引 用 类 型 转 换 成 Contractor 引 用 的 尝 试 是 肯 定 不 允 许 的, 因 为 Contractor 不 是 一 个 Manager 类 型 转 换 发 生 的 类 必 须 是 当 前 引 用 类 型 的 子 类 如 果 编 译 器 允 许 类 型 转 换, 那 么, 该 引 用 类 型 就 会 在 运 行 时 被 检 查 比 如, 如 果 第 100 页

101 instanceof 检 查 从 源 程 序 中 被 省 略, 而 被 类 型 转 换 的 对 象 实 际 上 不 是 它 应 被 类 型 转 换 进 去 的 类 型, 那 么, 就 会 发 生 一 个 运 行 时 错 误 (exception) 异 常 是 运 行 时 错 误 的 一 种 形 式, 而 且 是 后 面 章 节 的 主 题 4.6 static static 修 饰 符 static 修 饰 符 能 够 与 属 性 方 法 和 内 部 类 一 起 使 用, 表 示 是 静 态 的 类 中 的 静 态 变 量 和 静 态 方 法 能 够 与 类 名 一 起 使 用, 不 需 要 创 建 一 个 类 的 对 象 来 访 问 该 类 的 静 态 成 员 所 以 static 修 饰 的 变 量 又 称 作 类 变 量 这 与 实 例 变 量 不 同 实 例 变 量 总 是 用 对 象 来 访 问, 因 为 它 们 的 值 在 对 象 和 对 象 之 间 有 所 不 同 下 列 示 例 展 示 了 如 何 访 问 一 个 类 的 静 态 变 量 : class StaticModifier { static int i = 10; int j; StaticModifier() { j = 20; public class Test { public static void main(string args[]) { System.out.println(" 类 变 量 i=" + StaticModifier.i); StaticModifier s = new StaticModifier(); System.out.println(" 实 例 变 量 j=" + s.j); 上 述 程 序 的 输 出 是 : 类 变 量 i=10 实 例 变 量 j= static 属 性 的 内 存 分 配 在 上 面 的 例 子 中, 无 需 创 建 类 的 对 象 即 可 访 问 静 态 变 量 i 之 所 以 会 产 生 这 样 的 结 果, 是 因 为 编 译 器 只 为 整 个 类 创 建 了 一 个 静 态 变 量 的 副 本, 因 此 它 能 够 用 类 名 进 行 访 问 也 就 是 说 : 一 个 类 中, 一 个 static 变 量 只 会 有 一 个 内 存 空 间, 虽 然 有 多 个 类 实 例, 但 这 些 类 实 例 中 的 这 个 static 变 量 会 共 享 同 一 个 内 存 空 间 示 例 如 下 : public class Test { 第 101 页

102 public static void main(string[] args) { UserModel um1 = new UserModel(); um.username = " 张 三 "; um.country = "china"; UserModel um2 = new UserModel(); um2.username = " 李 四 "; um2.country = " 中 国 "; System.out.println("um1.userName==" + um1.username + " um1.country==" + um1.country ); System.out.println("um2.userName==" + um2.username + " um2.country==" + um2.country ); class UserModel { public static String country public String username; 运 行 结 果 : um1.username== 张 三 um1.country== 中 国 um2.username== 李 四 um2.country== 中 国 为 什 么 会 是 一 样 的 值 呢? 就 是 因 为 多 个 UserModel 实 例 中 的 静 态 变 量 country 是 共 享 同 一 内 存 空 间,um1.country 和 um2.country 其 实 指 向 的 都 是 同 一 个 内 存 空 间, 所 以 就 得 到 上 面 的 结 果 了 在 对 象 um2 创 建 前 的 运 行 后 内 存 分 配 示 意 图 如 下 : um1 china 张 三 country username 在 对 象 um2 创 建 后 的 运 行 后 内 存 分 配 示 意 图 如 下 : um1 um2 中 国 张 三 李 四 country username username 要 想 看 看 是 不 是 static 导 致 这 样 的 结 果, 你 可 以 尝 试 去 掉 country 前 面 的 static, 然 后 再 试 一 试, 看 看 结 果, 应 该 如 下 : um1.username== 张 三 um1.country==china um2.username== 李 四 um2.country== 中 国 还 有 一 点 也 很 重 要 :static 的 变 量 是 在 类 装 载 的 时 候 就 会 被 初 始 化 也 就 是 说, 只 要 类 被 装 载, 不 管 你 是 否 使 用 了 这 个 static 变 量, 它 都 会 被 初 始 化 小 结 一 下 : 类 变 量 (class variables) 用 关 键 字 static 修 饰, 在 类 加 载 的 时 候, 分 配 第 102 页

103 类 变 量 的 内 存, 以 后 再 生 成 类 的 实 例 对 象 时, 将 共 享 这 块 内 存 ( 类 变 量 ), 任 何 一 个 对 象 对 类 变 量 的 修 改, 都 会 影 响 其 它 对 象 外 部 有 两 种 访 问 方 式 : 通 过 对 象 来 访 问 或 通 过 类 名 来 访 问 static 的 基 本 规 则 有 关 静 态 变 量 或 方 法 的 一 些 要 点 如 下 : 在 同 一 个 类 中, 静 态 方 法 只 能 访 问 静 态 属 性 或 方 法, 静 态 方 法 不 能 够 直 接 调 用 非 静 态 属 性 或 方 法 ; 如 果 访 问 控 制 权 限 允 许, 静 态 属 性 和 静 态 方 法 可 以 使 用 类 名 加. 方 式 调 用 ; 也 可 以 使 用 实 例 加. 方 式 调 用 ; 静 态 方 法 中 不 存 在 当 前 对 象, 因 而 不 能 使 用 this, 当 然 也 不 能 使 用 super; 静 态 方 法 不 能 被 非 静 态 方 法 覆 盖 ; 构 造 方 法 不 允 许 声 明 为 static 的 ; 局 部 变 量 不 能 使 用 static 修 饰 ; static 方 法 可 以 用 类 名 来 访 问, 如 : public class GeneralFunction { public static int addup(int x, int y) { return x + y; public class UseGeneral { public void method() { int a = 9; int b = 10; int c = GeneralFunction.addUp(a, b); System.out.println("addUp() gives " + c); 因 为 static 方 法 不 需 它 所 属 的 类 的 任 何 实 例 就 会 被 调 用, 因 此 没 有 this 值 结 果 是, static 方 法 不 能 访 问 与 它 本 身 的 参 数 以 及 static 变 量 之 外 的 任 何 变 量, 访 问 非 静 态 变 量 的 尝 试 会 引 起 编 译 错 误 注 : 非 静 态 变 量 只 限 于 实 例, 并 只 能 通 过 实 例 引 用 被 访 问 静 态 初 始 器 静 态 块 静 态 初 始 器 (Static Initializer) 是 一 个 存 在 与 类 中 方 法 外 面 的 静 态 块 静 态 初 始 器 仅 仅 在 类 装 载 的 时 候 ( 第 一 次 使 用 类 的 时 候 ) 执 行 一 次 静 态 初 始 器 的 功 能 是 : 往 往 用 来 初 始 化 静 态 的 类 属 性 示 例 : class Count { public static int counter; static {// 只 运 行 一 次 第 103 页

104 counter = 123; System.out.println("Now in static block."); public void test() { System.out.println("test method==" + counter); public class Test { public static void main(string args[]) { System.out.println("counter=" + Count.counter); new Count().test(); 运 行 结 果 是 : Now in static block. counter=123 test method== 静 态 import( 选 修 ) 当 我 们 要 获 取 一 个 随 机 数 时, 写 法 是 : public class Test { public static void main(string[] args) { double randomnum = Math.random(); System.out.println("the randomnum==" + randomnum); 从 JDK5.0 开 始 可 以 写 为 : import static java.lang.math.random; public class Test { public static void main(string[] args) { double randomnum = random(); System.out.println("the randomnum==" + randomnum); 静 态 引 用 使 我 们 可 以 象 调 用 本 地 方 法 一 样 调 用 一 个 引 入 的 方 法, 当 我 们 需 要 引 入 同 一 个 类 的 多 个 方 法 时, 只 需 写 为 import static java.lang.math.* 即 可 这 样 的 引 用 方 式 对 于 枚 举 也 同 样 有 效 4.7 final 在 Java 中 声 明 类 属 性 和 方 法 时, 可 使 用 关 键 字 final 来 修 饰 final 所 标 记 的 成 分 具 有 终 态 的 特 征, 表 示 最 终 的 意 思 其 具 体 规 定 如 下 : 第 104 页

105 final 标 记 的 类 不 能 被 继 承 final 标 记 的 方 法 不 能 被 子 类 重 写 final 标 记 的 成 员 变 量 必 须 在 声 明 的 同 时 赋 值, 如 果 在 声 明 的 时 候 没 有 赋 值, 那 么 只 有 一 次 赋 值 的 机 会, 而 且 只 能 在 构 造 方 法 中 显 式 赋 值, 然 后 才 能 使 用 final 标 记 的 局 部 变 量 ( 成 员 变 量 或 局 部 变 量 ) 即 成 为 常 量, 只 能 赋 值 一 次 被 误 用, final 一 般 用 于 标 记 那 些 通 用 性 的 功 能 实 现 方 式 或 取 值 不 能 随 意 被 改 变 的 成 分, 以 避 免 例 如 实 现 数 学 三 角 方 法 幂 运 算 等 功 能 的 方 法, 以 及 数 学 常 量 π= e= 等 事 实 上, 为 确 保 这 终 态 性, 提 供 了 上 述 方 法 和 常 量 的 java.lang.math 类 也 已 被 定 义 为 final 的 需 要 注 意 的 是, 如 果 将 引 用 类 型 ( 即, 任 何 类 的 类 型 ) 的 变 量 标 记 为 final, 那 么 该 变 量 不 能 指 向 任 何 其 它 对 象 但 可 以 改 0 变 对 象 的 内 容, 因 为 只 有 引 用 本 身 是 final 的 如 果 变 量 被 标 记 为 final, 其 结 果 是 使 它 成 为 常 数 想 改 变 final 变 量 的 值 会 导 致 一 个 编 译 错 误 下 面 是 一 个 正 确 定 义 final 变 量 的 例 子 : public final int MAX_ARRAY_SIZE = 25; 例 final 关 键 字 程 序 :Test.java public final class Test { public static final int TOTAL_NUMBER = 5; public int id; public Test() { id = ++TOTAL_NUMBER;// 非 法, 对 final 变 量 TOTAL_NUMBER 进 行 二 次 赋 值 了 // 因 为 ++TOTAL_NUMBER 相 当 于 :TOTAL_NUMBER=TOTAL_NUMBER+1 public static void main(string[] args) { final Test t = new Test(); final int i = 10; final int j; j = 20; j = 30; // 非 法, 对 final 变 量 进 行 二 次 赋 值 Java 编 程 语 言 允 许 关 键 字 final 被 应 用 到 类 上 ( 放 在 class 关 键 字 前 面 ) 如 果 这 样 做 了, 类 便 不 能 被 再 派 生 出 子 类 比 如, 类 Java.lang.String 就 是 一 个 final 类 这 样 做 是 出 于 安 全 原 因, 因 为 它 保 证, 如 果 方 法 有 字 符 串 的 引 用, 它 肯 定 就 是 类 String 的 字 符 串, 而 不 是 某 个 其 它 类 的 字 符 串, 这 个 类 是 String 的 被 修 改 过 的 子 类, 因 为 String 可 能 被 恶 意 窜 改 过 方 法 也 可 以 被 标 记 为 final 被 标 记 为 final 的 方 法 不 能 被 覆 盖 这 是 由 于 安 全 原 因 如 果 方 法 具 有 不 能 被 改 变 的 实 现, 而 且 对 于 对 象 的 一 致 状 态 是 关 键 的, 那 么 就 要 使 方 法 成 为 第 105 页

106 final 被 声 明 为 final 的 方 法 有 时 被 用 于 优 化 编 译 器 能 产 生 直 接 对 方 法 调 用 的 代 码, 而 不 是 通 常 的 涉 及 运 行 时 查 找 的 虚 拟 方 法 调 用 被 标 记 为 static 或 private 的 方 法 被 自 动 地 final, 因 为 动 态 联 编 在 上 述 两 种 情 况 下 都 不 能 应 用 思 考 题 : 使 用 final 修 饰 的 变 量 是 最 终 的 不 可 修 改, 如 果 变 量 指 向 引 用 数 据 类 型, 请 问 是 变 量 的 引 用 不 可 以 修 改, 还 是 引 用 的 对 象 不 可 以 修 改 4.8 再 谈 Java 内 存 分 配 Java 程 序 运 行 时 的 内 存 结 构 分 成 : 方 法 区 栈 内 存 堆 内 存 本 地 方 法 栈 几 种 栈 和 堆 都 是 数 据 结 构 的 知 识, 如 果 不 清 楚, 没 有 关 系, 就 当 成 一 个 不 同 的 名 字 就 好 了, 下 面 的 讲 解 不 需 要 用 到 它 们 具 体 的 知 识 方 法 区 方 法 区 存 放 装 载 的 类 数 据 信 息 包 括 : (1) 基 本 信 息 : 每 个 类 的 全 限 定 名 每 个 类 的 直 接 超 类 的 全 限 定 名 ( 可 约 束 类 型 转 换 ) 该 类 是 类 还 是 接 口 该 类 型 的 访 问 修 饰 符 直 接 超 接 口 的 全 限 定 名 的 有 序 列 表 (2) 每 个 已 装 载 类 的 详 细 信 息 : 运 行 时 常 量 池 : 存 放 该 类 型 所 用 的 一 切 常 量 ( 直 接 常 量 和 对 其 它 类 型 字 段 方 法 的 符 号 引 用 ), 它 们 以 数 组 形 式 通 过 索 引 被 访 问, 是 外 部 调 用 与 类 联 系 及 类 型 对 象 化 的 桥 梁 它 是 类 文 件 ( 字 节 码 ) 常 量 池 的 运 行 时 表 示 字 段 信 息 : 类 中 声 明 的 每 一 个 字 段 的 信 息 ( 名, 类 型, 修 饰 符 ) 方 法 信 息 : 类 中 声 明 的 每 一 个 方 法 的 信 息 ( 名, 返 回 类 型, 参 数 类 型, 修 饰 符, 方 法 的 字 节 码 和 异 常 表 ) 静 态 变 量 : 到 类 classloader 的 引 用 : 即 到 该 类 的 类 装 载 器 的 引 用 到 类 class 的 引 用 : 虚 拟 机 为 每 一 个 被 装 载 的 类 型 创 建 一 个 class 实 例, 用 来 代 表 这 个 被 装 载 的 类 栈 内 存 Java 栈 内 存 以 帧 的 形 式 存 放 本 地 方 法 的 调 用 状 态 ( 包 括 方 法 调 用 的 参 数, 局 部 变 量, 中 间 结 果 等 ) 每 调 用 一 个 方 法 就 将 对 应 该 方 法 的 方 法 帧 压 入 Java 栈, 成 为 当 前 方 法 帧 当 调 用 结 束 ( 返 回 ) 时, 就 弹 出 该 帧 编 译 器 将 源 代 码 编 译 成 字 节 码 (.class) 时, 就 已 经 将 各 种 类 型 的 方 法 的 局 部 变 量, 操 作 数 第 106 页

107 栈 大 小 确 定 并 放 在 字 节 码 中, 随 着 类 一 并 装 载 入 方 法 区 当 调 用 方 法 时, 通 过 访 问 方 法 区 中 的 类 的 信 息, 得 到 局 部 变 量 以 及 操 作 数 栈 的 大 小 也 就 是 说 : 在 方 法 中 定 义 的 一 些 基 本 类 型 的 变 量 和 对 象 的 引 用 变 量 都 在 方 法 的 栈 内 存 中 分 配 当 在 一 段 代 码 块 定 义 一 个 变 量 时,Java 就 在 栈 中 为 这 个 变 量 分 配 内 存 空 间, 当 超 过 变 量 的 作 用 域 后,Java 会 自 动 释 放 掉 为 该 变 量 所 分 配 的 内 存 空 间, 该 内 存 空 间 可 以 立 即 被 另 作 它 用 栈 内 存 的 构 成 : Java 栈 内 存 由 局 部 变 量 区 操 作 数 栈 帧 数 据 区 组 成 (1) 局 部 变 量 区 为 一 个 以 字 为 单 位 的 数 组, 每 个 数 组 元 素 对 应 一 个 局 部 变 量 的 值 调 用 方 法 时, 将 方 法 的 局 部 变 量 组 成 一 个 数 组, 通 过 索 引 来 访 问 若 为 非 静 态 方 法, 则 加 入 一 个 隐 含 的 引 用 参 数 this, 该 参 数 指 向 调 用 这 个 方 法 的 对 象 而 静 态 方 法 则 没 有 this 参 数 因 此, 对 象 无 法 调 用 静 态 方 法 (2) 操 作 数 栈 也 是 一 个 数 组, 但 是 通 过 栈 操 作 来 访 问 所 谓 操 作 数 是 那 些 被 指 令 操 作 的 数 据 当 需 要 对 参 数 操 作 时 如 a=b+c, 就 将 即 将 被 操 作 的 参 数 压 栈, 如 将 b 和 c 压 栈, 然 后 由 操 作 指 令 将 它 们 弹 出, 并 执 行 操 作 虚 拟 机 将 操 作 数 栈 作 为 工 作 区 (3) 帧 数 据 区 处 理 常 量 池 解 析, 异 常 处 理 等 堆 内 存 堆 内 存 用 来 存 放 由 new 创 建 的 对 象 和 数 组 在 堆 中 分 配 的 内 存, 由 Java 虚 拟 机 的 自 动 垃 圾 回 收 器 来 管 理 在 堆 中 产 生 了 一 个 数 组 或 对 象 后, 还 可 以 在 栈 中 定 义 一 个 特 殊 的 变 量, 让 栈 中 这 个 变 量 的 取 值 等 于 数 组 或 对 象 在 堆 内 存 中 的 首 地 址, 栈 中 的 这 个 变 量 就 成 了 数 组 或 对 象 的 引 用 变 量 引 用 变 量 就 相 当 于 是 为 数 组 或 对 象 起 的 一 个 名 称, 以 后 就 可 以 在 程 序 中 使 用 栈 中 的 引 用 变 量 来 访 问 堆 中 的 数 组 或 对 象 栈 内 存 和 堆 内 存 比 较 栈 与 堆 都 是 Java 用 来 在 内 存 中 存 放 数 据 的 地 方 与 C++ 不 同,Java 自 动 管 理 栈 和 堆, 程 序 员 不 能 直 接 地 设 置 栈 或 堆 Java 的 堆 是 一 个 运 行 时 数 据 区, 对 象 从 中 分 配 空 间 堆 的 优 势 是 可 以 动 态 地 分 配 内 存 大 小, 生 存 期 也 不 必 事 先 告 诉 编 译 器, 因 为 它 是 在 运 行 时 动 态 分 配 内 存 的,Java 的 垃 圾 收 集 器 会 自 动 收 走 这 些 不 再 使 用 的 数 据 但 缺 点 是, 由 于 要 在 运 行 时 动 态 分 配 内 存, 存 取 速 度 较 慢 栈 的 优 势 是, 存 取 速 度 比 堆 要 快, 仅 次 于 寄 存 器, 栈 数 据 可 以 共 享 但 缺 点 是, 存 在 栈 中 的 数 据 大 小 与 生 存 期 必 须 是 确 定 的, 缺 乏 灵 活 性 栈 中 主 要 存 放 一 些 基 本 类 型 的 变 量 ( int, short, long, byte, float, double, boolean, char) 和 对 象 句 柄 栈 有 一 个 很 重 要 的 特 殊 性, 就 是 存 在 栈 中 的 数 据 可 以 共 享 假 设 我 们 同 时 定 义 : int a = 3; int b = 3; 第 107 页

108 编 译 器 先 处 理 int a=3; 首 先 它 会 在 栈 中 创 建 一 个 变 量 为 a 的 引 用, 然 后 查 找 栈 中 是 否 有 3 这 个 值, 如 果 没 找 到, 就 将 3 存 放 进 来, 然 后 将 a 指 向 3 接 着 处 理 int b=3; 在 创 建 完 b 的 引 用 变 量 后, 因 为 在 栈 中 已 经 有 3 这 个 值, 便 将 b 直 接 指 向 3 这 样, 就 出 现 了 a 与 b 同 时 均 指 向 3 的 情 况 内 存 示 意 图 如 下 : 变 量 a 3 变 量 b 这 时, 如 果 再 令 b=4; 那 么 编 译 器 会 重 新 搜 索 栈 中 是 否 有 4 值, 如 果 没 有, 则 将 4 存 放 进 来, 并 令 a 指 向 4; 如 果 已 经 有 了, 则 直 接 将 a 指 向 这 个 地 址 因 此 a 值 的 改 变 不 会 影 响 到 b 的 值 要 注 意 这 种 数 据 的 共 享 与 两 个 对 象 的 引 用 同 时 指 向 一 个 对 象 的 这 种 共 享 是 不 同 的, 因 为 这 种 情 况 a 的 修 改 并 不 会 影 响 到 b, 它 是 由 编 译 器 完 成 的, 它 有 利 于 节 省 空 间 此 时 的 内 存 分 配 示 意 图 如 下 : 变 量 a 3 变 量 b 4 而 一 个 对 象 引 用 变 量 修 改 了 这 个 对 象 的 内 部 状 态, 会 影 响 到 另 一 个 对 象 引 用 变 量 本 地 方 法 栈 内 存 当 一 个 线 程 调 用 本 地 方 法 时, 它 就 不 再 受 到 虚 拟 机 关 于 结 构 和 安 全 限 制 方 面 的 约 束, 它 既 可 以 访 问 虚 拟 机 的 运 行 期 数 据 区, 也 可 以 使 用 本 地 处 理 器 以 及 任 何 类 型 的 栈 例 如, 本 地 栈 是 一 个 C 语 言 的 栈, 那 么 当 C 程 序 调 用 C 函 数 时, 函 数 的 参 数 以 某 种 顺 序 被 压 入 栈, 结 果 则 返 回 给 调 用 函 数 在 实 现 Java 虚 拟 机 时, 本 地 方 法 接 口 使 用 的 是 C 语 言 的 模 型 栈, 那 么 它 的 本 地 方 法 栈 的 调 度 与 使 用 则 完 全 与 C 语 言 的 栈 相 同 Java 通 过 Java 本 地 接 口 JNI(Java Native Interface) 来 调 用 其 它 语 言 编 写 的 程 序, 在 Java 里 面 用 native 修 饰 符 来 描 述 一 个 方 法 是 本 地 方 法 这 个 了 解 一 下 就 好 了, 在 我 们 的 课 程 中 不 会 涉 及 到 String 的 内 存 分 配 String 是 一 个 特 殊 的 包 装 类 数 据 可 以 用 : String str = new String("abc"); String str = "abc"; 两 种 的 形 式 来 创 建, 第 一 种 是 用 new() 来 新 建 对 象 的, 它 会 在 存 放 于 堆 中 每 调 用 一 次 就 会 创 建 一 个 新 的 对 象 而 第 二 种 是 先 在 栈 中 创 建 一 个 对 String 类 的 对 象 引 用 变 量 str, 然 后 查 找 栈 中 有 没 有 存 放 "abc", 如 果 没 有, 则 将 "abc" 存 放 进 栈, 并 令 str 指 向 "abc", 如 果 已 第 108 页

109 经 有 "abc" 则 直 接 令 str 指 向 "abc" 比 较 类 里 面 的 数 值 是 否 相 等 时, 用 equals() 方 法 ; 当 测 试 两 个 包 装 类 的 引 用 是 否 指 向 同 一 个 对 象 时, 用 = =, 下 面 用 例 子 说 明 上 面 的 理 论 String str1 = "abc"; String str2 = "abc"; System.out.println(str1==str2); //true 可 以 看 出 str1 和 str2 是 指 向 同 一 个 对 象 的 变 量 str1 "abc" 变 量 str2 String str1 = new String ("abc"); String str2 = new String ("abc"); System.out.println(str1==str2); // false 用 new 的 方 式 是 生 成 不 同 的 对 象 每 一 次 生 成 一 个 变 量 str1 变 量 str2 "abc" "abc" 因 此 用 第 一 种 方 式 创 建 多 个 "abc" 字 符 串, 在 内 存 中 其 实 只 存 在 一 个 对 象 而 已 这 种 写 法 有 利 于 节 省 内 存 空 间 同 时 它 可 以 在 一 定 程 度 上 提 高 程 序 的 运 行 速 度, 因 为 JVM 会 自 动 根 据 栈 中 数 据 的 实 际 情 况 来 决 定 是 否 有 必 要 创 建 新 对 象 而 对 于 String str = new String("abc"); 的 代 码, 则 一 概 在 堆 中 创 建 新 对 象, 而 不 管 其 字 符 串 值 是 否 相 等, 是 否 有 必 要 创 建 新 对 象, 从 而 加 重 了 程 序 的 负 担 另 一 方 面, 要 注 意 : 我 们 在 使 用 诸 如 String str = "abc"; 的 格 式 时, 总 是 想 当 然 地 认 为, 创 建 了 String 类 的 对 象 str 担 心 陷 阱! 对 象 可 能 并 没 有 被 创 建! 而 可 能 只 是 指 向 一 个 先 前 已 经 创 建 的 对 象 只 有 通 过 new() 方 法 才 能 保 证 每 次 都 创 建 一 个 新 的 对 象 由 于 String 类 的 值 不 可 变 性 (immutable), 当 String 变 量 需 要 经 常 变 换 其 值 时, 应 该 考 虑 使 用 StringBuffer 或 StringBuilder 类, 以 提 高 程 序 效 率 第 109 页

110 4.9 学 习 目 标 1. OOP( 面 向 对 象 ) 语 言 的 三 大 特 征 是? 2. 理 解 什 么 是 封 装, 封 装 的 好 处 3. 理 解 什 么 是 类 的 继 承, 继 承 的 好 处 4. 理 解 is-a 关 系 5. 理 解 父 子 类 的 初 始 化 顺 序 6. 理 解 类 的 单 继 承 性 7. 理 解 构 造 方 法 不 能 被 继 承 8. super 关 键 字 的 用 法, 为 什 么 使 用 super? 9. 什 么 是 方 法 的 覆 盖? 什 么 情 况 下 出 现? 10. 方 法 覆 盖 的 规 则? 11. 什 么 是 重 载? 什 么 情 况 下 出 现? 12. 简 述 重 载 的 规 则 13. 如 何 调 用 父 类 的 构 造 函 数? 如 何 调 用 自 己 的 构 造 函 数? 14. 如 何 确 定 在 多 态 的 调 用 中, 究 竟 是 调 用 的 那 个 方 法? 15. Instanceof 运 算 符 的 用 法 16. static 修 饰 符 的 功 能 是? 可 以 用 在 什 么 地 方? 怎 么 访 问? 17. static 的 基 本 规 则 18. final 修 饰 符 的 功 能 是? 可 以 用 在 什 么 地 方? 19. final 的 基 本 规 则 20. java 中 什 么 数 据 存 储 在 堆 内 存, 什 么 数 据 存 储 在 栈 内 存 21. 堆 内 存 有 什 么 特 点, 栈 内 存 有 什 么 特 点 第 110 页

111 4.10 练 习 1. 创 建 一 个 构 造 方 法 重 载 的 类, 并 用 另 一 个 类 调 用 2. 创 建 Rodent( 啮 齿 动 物 ):Mouse( 老 鼠 ),Gerbil( 鼹 鼠 ),Hamster( 大 颊 鼠 ) 等 的 一 个 继 承 分 级 结 构 在 基 础 类 中, 提 供 适 用 于 所 有 Rodent 的 方 法, 并 在 衍 生 类 中 覆 盖 它 们, 从 而 根 据 不 同 类 型 的 Rodent 采 取 不 同 的 行 动 创 建 一 个 Rodent 数 组, 在 其 中 填 充 不 同 类 型 的 Rodent, 然 后 调 用 自 己 的 基 础 类 方 法, 看 看 会 有 什 么 情 况 发 生 3. 编 写 MyPoint 的 一 个 子 类 MyXYZ, 表 示 三 维 坐 标 点, 重 写 tostring 方 法 用 来 显 示 这 个 对 象 的 x y z 的 值, 如 显 示 (1,2,3), 最 后 用 main 方 法 测 试 4. 当 你 试 图 编 译 和 执 行 下 面 的 程 序 时 会 发 生 什 么? class Mystery { String s; public static void main(string[] args) { Mystery m = new Mystery(); m.go(); void Mystery() { s = "constructor"; void go() { System.out.println(s); 选 择 下 面 的 正 确 答 案 : A. 编 译 不 通 过 B. 编 译 通 过 但 运 行 时 产 生 异 常 C. 代 码 运 行 但 屏 幕 上 看 不 到 任 何 东 西 D. 代 码 运 行, 屏 幕 上 看 到 constructor E. 代 码 运 行, 屏 幕 上 看 到 null 5. 当 编 译 和 运 行 下 列 程 序 段 时, 会 发 生 什 么? class Person { class Woman extends Person { class Man extends Person { 第 111 页

112 public class Test { public static void main(string argv[]) { Man m = new Man(); Woman w = (Woman) new Man(); A. 通 过 编 译 和 并 正 常 运 行 B. 编 译 时 出 现 例 外 C. 编 译 通 过, 运 行 时 出 现 例 外 D. 编 译 不 通 过 6. 对 于 下 列 代 码 : 1 class Person { 2 public void printvalue(int i, int j) {... 3 public void printvalue(int i){ public class Teacher extends Person { 6 public void printvalue() {... 7 public void printvalue(int i) {... 8 public static void main(string args[]){ 9 Person t = new Teacher(); 10 t.printvalue(10); 第 10 行 语 句 将 调 用 哪 行 语 句? A. line 2 B. line 3 C. line 6 D. line 7 7. 下 列 代 码 运 行 结 果 是 什 么? public class Bool { static boolean b; public static void main(string[] args) { int x = 0; if (b) { x = 1; else if (b == false) { x = 2; else if (b) { x = 3; else { x = 4; System.out.println("x= " + x); 第 112 页

113 8. 完 成 此 段 代 码 可 以 单 独 添 加 哪 些 选 项? 1. public class Test { public static void main(string[] args) { System.out.println("c=" + c); A. 在 第 2 行 加 上 语 句 static char c; B. 在 第 2 行 加 上 语 句 char c; C. 在 第 4 行 加 上 语 句 static char c; D. 在 第 4 行 加 上 语 句 char c= f ; 9. 下 列 代 码 运 行 结 果 是 什 么? public class A { public static void main(stirng[] args) { int m = 2; int p = 1; int t = 0; for (; p < 5; p++) { if (t++ > m) { m = p + t; System.out.println("t equals" + t); A. 2 B. 4 C. 6 D 设 计 个 Circle 类, 其 属 性 为 圆 心 点 ( 类 型 为 前 面 设 计 的 类 MyPoint) 和 半 径, 并 为 此 类 编 写 以 下 三 个 方 法 : 一 是 计 算 圆 面 积 的 calarea() 方 法 ; 二 是 计 算 周 长 的 callength(); 三 是 boolean incircle(mypoint mp) 方 法, 功 能 是 测 试 作 为 参 数 的 某 个 点 是 否 在 当 前 对 象 圆 内 ( 圆 内, 包 括 圆 上 返 回 true; 在 圆 外, 返 回 false 第 113 页

114 5 数 组 和 枚 举 5.1 数 组 的 声 明 和 创 建 数 组 的 声 明 数 组 是 由 相 同 类 型 的 若 干 项 数 据 组 成 的 一 个 数 据 集 合, 数 组 中 的 每 个 数 据 称 为 元 素 也 就 是 说 数 组 是 用 来 集 合 相 同 类 型 的 对 象, 可 以 是 原 始 数 据 类 型 或 引 用 数 据 类 型 数 组 声 明 实 际 是 创 建 一 个 引 用, 通 过 代 表 引 用 的 这 个 名 字 来 引 用 数 组 数 组 声 明 格 式 如 下 : 数 据 类 型 标 识 符 [] 示 例 : char s[]; // 声 明 一 个 数 据 类 型 为 字 符 型 的 数 组 s Point arr[]; // 声 明 一 个 数 据 类 型 为 Point 的 数 组 arr 在 Java 编 程 语 言 中, 数 组 是 一 个 对 象, 声 明 不 能 创 建 对 象 本 身, 而 创 建 的 是 一 个 引 用, 该 引 用 可 被 用 来 引 用 数 组 数 组 元 素 使 用 的 实 际 内 存 可 由 new 语 句 或 数 组 初 始 化 软 件 动 态 分 配 在 后 面, 你 将 看 到 如 何 创 建 和 初 始 化 实 际 数 组 上 述 这 种 将 方 括 号 置 于 变 量 名 之 后 的 声 明 数 组 的 格 式, 是 用 于 C C++ 和 Java 编 程 语 言 的 标 准 格 式 这 种 格 式 会 使 声 明 的 格 式 复 杂 难 懂, 因 而,Java 编 程 语 言 允 许 一 种 替 代 的 格 式, 该 格 式 中 的 方 括 号 位 于 变 量 名 的 左 边 : char[] s; Point[] arr; 这 样 的 结 果 是, 你 可 以 认 为 类 型 部 分 在 左, 而 变 量 名 在 右 上 述 两 种 格 式 并 存, 你 可 选 择 一 种 你 习 惯 的 方 式 声 明 不 指 出 数 组 的 实 际 大 小 注 意 ---- 当 数 组 声 明 的 方 括 号 在 左 边 时, 该 方 括 号 可 应 用 于 所 有 位 于 其 右 的 变 量 创 建 数 组 数 据 对 象 和 其 他 Java 对 象 一 样, 使 用 关 键 字 new 创 建 创 建 的 时 候 要 指 明 数 组 的 长 度 s = new char [20]; p = new Point [100]; 第 一 行 创 建 了 一 个 20 个 char 类 型 元 素 的 数 组, 在 堆 区 为 数 组 分 配 内 存 空 间, 每 个 元 素 都 是 char 类 型 的, 占 2 个 字 节, 因 此 整 个 数 组 对 象 再 内 存 中 占 用 40 个 字 节 为 每 个 元 素 赋 予 其 数 据 类 型 的 默 认 值, 即 '\u0000' 返 回 数 组 对 象 的 引 用 赋 值 给 变 量 s 第 二 行 创 建 了 一 个 100 个 类 型 Point 的 变 量, 然 而, 它 并 不 是 创 建 100 个 Point 对 象 ; 创 第 114 页

115 建 100 个 对 象 的 工 作 必 须 分 别 完 成 如 下 : p[0] = new Point(); p[1] = new Point(); 用 来 指 示 单 个 数 组 元 素 的 下 标 必 须 总 是 从 0 开 始, 并 保 持 在 合 法 范 围 之 内 -- 大 于 0 或 等 于 0 并 小 于 数 组 长 度 任 何 访 问 在 上 述 界 限 之 外 的 数 组 元 素 的 企 图 都 会 引 起 运 行 时 出 错 数 组 的 下 标 也 称 为 数 组 的 索 引, 必 须 是 整 数 或 者 整 数 表 达 式, 如 下 : int i[] = new int[(9-2) * 3];// 这 是 合 法 的 其 实, 声 明 和 创 建 可 以 定 义 到 一 行, 而 不 用 分 开 写 数 组 的 初 始 化 当 创 建 一 个 数 组 时, 每 个 元 素 都 被 自 动 使 用 默 认 值 进 行 初 始 化 在 上 述 char 数 组 s 的 例 子 中, 每 个 值 都 被 初 始 化 为 0 (\u0000-null) 字 符 ; 在 数 组 p 的 例 子 中, 每 个 值 都 被 初 始 化 为 null, 表 明 它 还 未 引 用 一 个 Point 对 象 在 经 过 赋 值 p[0]=new Point() 之 后, 数 组 的 第 一 个 元 素 引 用 为 实 际 Point 对 象 注 意 -- 所 有 变 量 的 初 始 化 ( 包 括 数 组 元 素 ) 是 保 证 系 统 安 全 的 基 础, 变 量 绝 不 能 在 未 初 始 化 状 态 使 用 Java 编 程 语 言 允 许 使 用 下 列 形 式 快 速 创 建 数 组, 直 接 定 义 并 初 始 化 : String names[] = { "Georgianna", "Jen", "Simon" ; 其 结 果 与 下 列 代 码 等 同 : String names[]; names = new String[3]; names[0]="georgianna"; names[1]="jen"; names[2]="simon"; 这 速 记 法 可 用 在 任 何 元 素 类 型 例 如 : Myclass array[] = { new Myclass(), new Myclass(), new Myclass() ; 适 当 的 类 类 型 的 常 数 值 也 可 被 使 用 : import java.awt.color; Color palette [] ={ Color.blue, Color.red, Color.white ; 第 115 页

116 5.1.4 数 组 的 内 存 分 配 数 组 一 旦 被 创 建, 在 内 存 里 面 占 用 连 续 的 内 存 地 址 度 数 组 还 具 有 一 个 非 常 重 要 的 特 点 数 组 的 静 态 性 : 数 组 一 旦 被 创 建, 就 不 能 更 改 数 组 的 长 比 如, 定 义 数 组 如 下 : Point[] p = new Point [3]; 其 中 p 是 数 组 名, 数 组 长 度 是 3, 数 组 在 被 创 建 的 时 候, 内 存 示 意 图 如 下 : p 0x1fb8ee3 p[0] null p[1] null p[2] null 为 数 组 初 始 化 : p[0] = new Point() ; p[1] = new Point() ; p[2] = new Point() ; 内 存 示 意 图 如 下 : p 0x1fb8ee3 p[0] 0x1fb8d32 Point p[1] 0x1fb8ef3 Point p[2] 0x1fb8145 Point 5.2 数 组 元 素 的 访 问 使 用 length 属 性 在 Java 编 程 语 言 中, 所 有 数 组 的 下 标 都 从 0 开 始 一 个 数 组 中 元 素 的 数 量 被 作 为 具 有 length 属 性 的 部 分 数 组 对 象 而 存 储 ; 这 个 值 被 用 来 检 查 所 有 运 行 时 访 问 的 界 限 如 果 发 生 了 一 个 越 出 界 限 的 访 问, 那 么 运 行 时 的 报 错 也 就 出 现 了 使 用 length 属 性 的 例 子 如 下 : int[] list =new int [10]; for(int i=0;i<list.length;i++){ System.out.println( list[i] ); 使 用 length 属 性 使 得 程 序 的 维 护 变 得 更 简 单 第 116 页

117 所 有 元 素 的 访 问 就 通 过 数 组 的 下 标 来 访 问, 如 上 例 的 list[i], 随 着 i 的 值 发 生 变 化, 就 依 次 访 问 list[0] list[1] list[2] 如 果 想 要 给 某 个 数 组 元 素 赋 值, 如 下 方 式 : list[0]=5; list[1]=6; 示 例 : 假 如 定 义 一 个 数 组 : int c [] = new int[5]; // 进 行 赋 值 的 语 句 对 数 组 进 行 赋 值 后, 内 存 示 意 图 如 下 : c C[0] 35 C[1] 46 C[2] 57 C[3] 21 C[5] 135 然 后 就 可 以 根 据 数 组 名 [ 下 标 ] 来 取 值 了 如 : int a = c[3]; 结 果 就 是 : 从 数 组 中 取 出 下 标 为 3 的 元 素 的 值 21, 然 后 赋 值 给 a 更 优 化 的 for 循 环 语 句 在 访 问 数 组 的 时 候, 经 常 使 用 for 循 环 语 句 从 JDK5.0 开 始, 提 供 了 一 个 更 好 的 for 循 环 语 句 的 写 法, 示 例 如 下 : public class Test { public static void main(string args[]) { int a[] = new int[3]; // 旧 的 写 法, 赋 值 for (int i = 0; i < a.length; i++) { a[i] = i; // 新 的 写 法, 取 值 for (int i : a) { System.out.println(i); 显 然 JDK5.0 版 本 的 写 法 比 以 前 是 大 大 简 化 了 第 117 页

118 5.3 多 维 数 组 多 维 数 组 的 基 础 知 识 Java 编 程 语 言 没 有 象 其 它 语 言 那 样 提 供 多 维 数 组 因 为 一 个 数 组 可 被 声 明 为 具 有 任 何 基 础 类 型, 所 以 你 可 以 创 建 数 组 的 数 组 ( 和 数 组 的 数 组 的 数 组, 等 等 ) 一 个 二 维 数 组 如 下 例 所 示 : int twodim[][] = new int[4][]; twodim[0] = new int[5]; twodim[1] = new int[5]; 首 次 调 用 new 而 创 建 的 对 象 是 一 个 数 组, 它 包 含 4 个 元 素, 每 个 元 素 对 类 型 array of int 的 元 素 都 是 一 个 null 引 用 并 且 必 须 将 数 组 的 每 个 点 分 别 初 始 化 因 为 这 种 对 每 个 元 素 的 分 别 初 始 化, 所 以 有 可 能 创 建 非 矩 形 数 组 的 数 组 也 就 是 说, twodim 的 元 素 可 按 如 下 方 式 初 始 化 : twodim[0] = new int [2]; twodim[1] = new int [4]; twodim[2] = new int [6]; twodim[3] = new int [8]; 由 于 此 种 初 始 化 的 方 法 烦 琐 乏 味, 而 且 矩 形 数 组 的 数 组 是 最 通 用 的 形 式, 因 而 产 生 了 一 种 速 记 方 法 来 创 建 二 维 数 组 例 如 : int twodim[][] = new int [3][4]; 可 被 用 来 创 建 一 个 每 个 数 组 有 4 个 整 数 类 型 的 3 个 数 组 的 数 组 可 以 理 解 成 为 如 下 表 格 所 示 : twodim[0][0] twodim[0][1] twodim[0][2] twodim[0][3] twodim[1][0] twodim[1][1] twodim[1][2] twodim[1][3] twodim[2][0] twodim[2][1] twodim[2][2] twodim[2][3] 第 一 个 方 括 号 中 的 数 字 表 示 行, 第 二 个 方 括 号 中 的 数 字 表 示 列, 注 意 都 是 从 0 开 始 的 尽 管 声 明 的 格 式 允 许 方 括 号 在 变 量 名 左 边 或 者 右 边, 但 此 种 灵 活 性 不 适 用 于 数 组 句 法 的 其 它 方 面 例 如 : new int [][4] 是 非 法 的 示 例 class FillArray { public static void main(string args[]) { int[][] matrix = new int[4][5]; // 二 维 数 组 的 声 明 和 创 建 for (int row = 0; row < 4; row++) { for (int col = 0; col < 5; col++) { 第 118 页

119 matrix[row][col] = row + col; // 二 维 数 组 的 访 问, 为 元 素 赋 值 当 然 也 可 以 直 接 定 义 并 赋 值, 如 下 : double[][] c = { { 1.0, 2.0, 3.0, 4.0, { 0.0, 1.0, 0.0, 0.0, { 0.0, 0.0, 1.0, 0.0 ; 从 上 面 可 以 看 得 很 清 楚, 二 维 数 组 其 实 就 是 一 维 的 一 维 数 组 多 维 数 组 的 本 质 N 维 数 组 就 是 一 维 的 N-1 维 数 组, 比 如 : 三 维 数 组 就 是 一 维 的 二 维 数 组 三 维 以 至 多 维 数 组 都 是 一 个 思 路, 一 维 数 组 二 维 数 组 三 维 数 组 的 实 例 : class Fill3DArray { public static void main(string args[]) { int[][][] M = new int[4][5][3]; for (int row = 0; row < 4; row++) { for (int col = 0; col < 5; col++) { for (int ver = 0; ver < 3; ver++) { M[row][col][ver] = row + col + ver; 5.4 数 组 的 复 制 组 : 数 组 一 旦 创 建 后, 其 大 小 不 可 调 整 然 而, 你 可 使 用 相 同 的 引 用 变 量 来 引 用 一 个 全 新 的 数 int myarray []= new int [6]; myarray = new int [10]; 在 这 种 情 况 下, 第 一 个 数 组 被 有 效 地 丢 失, 除 非 对 它 的 其 它 引 用 保 留 在 其 它 地 方 Java 编 程 语 言 在 arraycopy() 例 如,araycopy 可 作 如 下 使 用 : System 类 中 提 供 了 一 种 特 殊 方 法 拷 贝 数 组, 该 方 法 被 称 作 // 原 始 数 组 第 119 页

120 int myarray[] = { 1, 2, 3, 4, 5, 6 ; // 新 的 数 组, 比 原 始 数 组 大 int hold[] = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 ; // 把 原 始 数 组 的 值 拷 贝 到 新 的 数 组 System.arraycopy(myArray, 0, hold, 0, myarray.length); 拷 贝 完 成 后, 数 组 hold 有 如 下 内 容 :1,2,3,4,5,6,4,3,2,1 不 改 变 注 意 在 处 理 对 象 数 组 时,System.arraycopy() 拷 贝 的 是 引 用, 而 不 是 对 象 对 象 本 身 5.5 数 组 的 排 序 基 本 的 排 序 算 法 冒 泡 排 序 对 几 个 无 序 的 数 字 进 行 排 序, 比 较 常 用 的 方 法 是 冒 泡 排 序 法 冒 泡 法 排 序 是 一 个 比 较 简 单 的 排 序 方 法, 在 待 排 序 的 数 列 基 本 有 序 的 情 况 下 排 序 速 度 较 快 基 本 思 路 : 对 未 排 序 的 各 元 素 从 头 到 尾 依 次 比 较 相 邻 的 两 个 元 素 是 否 逆 序 ( 与 欲 排 顺 序 相 反 ), 若 逆 序 就 交 换 这 两 元 素, 经 过 第 一 轮 比 较 排 序 后 便 可 把 最 大 ( 或 最 小 ) 的 元 素 排 好, 然 后 再 用 同 样 的 方 法 把 剩 下 的 元 素 逐 个 进 行 比 较, 就 得 到 了 你 所 要 的 顺 序 可 以 看 出 如 果 有 N 个 元 素, 那 么 一 共 要 进 行 N-1 轮 比 较, 第 I 轮 要 进 行 N-I 次 比 较 ( 如 : 有 5 个 元 素, 则 要 进 行 5-1 轮 比 较 第 3 轮 则 要 进 行 5-3 次 比 较 ) 示 例 如 下 : public class Test3 { public static void main(string[] args) { // 需 要 排 序 的 数 组, 目 前 是 按 照 升 序 排 列 的 int a[] = new int[5]; a[0] = 3; a[1] = 4; a[2] = 1; a[3] = 5; a[4] = 2; // 冒 泡 排 序 for (int i = 0; i < a.length-1; i++) { for (int j = 0; j < a.length-1; j++) { // 判 断 相 邻 的 两 个 元 素 是 否 逆 序 if (a[j] > a[j+1]) { int temp = a[j]; a[j] = a[j+1]; a[j+1] = temp; 第 120 页

121 // 检 测 一 下 排 序 的 结 果 for (int i : a) { System.out.println("i=" + i); 运 行 结 果 : i=1 i=2 i=3 i=4 i=5 如 果 你 想 要 按 照 降 序 排 列, 很 简 单, 只 需 把 :if(a[j] > a[j+1]) 改 成 :if(a[j] < a[j+1]) 就 可 以 了 选 择 排 序 基 本 思 路 : 从 所 有 元 素 中 选 择 一 个 最 小 元 素 a[i] 放 在 a[0]( 即 让 最 小 元 素 a[i] 与 a[0] 交 换 ), 作 为 第 一 轮 ; 第 二 轮 是 从 a[1] 开 始 到 最 后 的 各 个 元 素 中 选 择 一 个 最 小 元 素, 放 在 a[1] 中 ; 依 次 类 推 n 个 数 要 进 行 (n-1) 轮 比 较 的 次 数 与 冒 泡 法 一 样 多, 但 是 在 每 一 轮 中 只 进 行 一 次 交 换, 比 冒 泡 法 的 交 换 次 数 少, 相 对 于 冒 泡 法 效 率 高 示 例 如 下 : public class Test { public static void main(string[] args) { // 需 要 排 序 的 数 组, 目 前 是 按 照 升 序 排 列 的 int a[] = new int[5]; a[0] = 3; a[1] = 4; a[2] = 1; a[3] = 5; a[4] = 2; // 选 择 法 排 序 int temp; for (int i = 0; i < a.length; i++) { int lowindex = i; // 找 出 最 小 的 一 个 的 索 引 for (int j = i + 1; j < a.length; j++) { if (a[j] < a[lowindex]) { lowindex = j; // 交 换 temp = a[i]; a[i] = a[lowindex]; a[lowindex] = temp; // 检 测 一 下 排 序 的 结 果 for (int i : a) { 第 121 页

122 System.out.println("i=" + i); 运 行 结 果 : i=1 i=2 i=3 i=4 i=5 如 果 你 想 要 按 照 降 序 排 列, 很 简 单, 只 需 要 把 :if (a[j] <a[lowindex]) 这 句 话 修 改 成 : if (a[j] > a[lowindex]) 就 可 以 了 插 入 法 排 序 基 本 思 路 : 每 拿 到 一 个 元 素, 都 要 将 这 个 元 素 与 所 有 它 之 前 的 元 素 遍 历 比 较 一 遍, 让 符 合 排 序 顺 序 的 元 素 挨 个 移 动 到 当 前 范 围 内 它 最 应 该 出 现 的 位 置 举 个 例 子 来 说, 就 用 前 面 的 数 组, 我 们 要 对 一 个 有 5 个 元 素 的 数 组 进 行 升 序 排 列, 假 设 第 一 个 元 素 的 值 被 假 定 为 已 排 好 序 了, 那 么 我 们 就 将 第 2 个 元 素 与 数 组 中 的 部 分 进 行 比 较, 如 果 第 2 个 元 素 的 值 较 小, 则 将 它 插 入 到 第 1 个 元 素 的 前 面, 现 在 就 有 两 个 元 素 排 好 序 了, 我 们 再 将 没 有 排 序 的 元 素 与 排 好 序 的 元 素 列 表 进 行 比 较, 同 样, 如 果 小 于 第 一 个 元 素, 就 将 它 插 入 到 第 一 个 元 素 前 面, 但 是, 如 果 大 于 第 一 个 元 素 的 话, 我 们 就 将 它 再 与 第 2 个 元 素 的 值 进 行 比 较, 小 于 的 话 就 排 在 第 2 个 元 素 前 面, 大 于 的 话, 就 排 在 第 2 个 元 素 的 后 面 以 此 类 推, 直 到 最 后 一 个 元 素 排 好 序 示 例 如 下 : public class Test { public static void main(string[] args) { // 需 要 排 序 的 数 组, 目 前 是 按 照 升 序 排 列 的 int a[] = new int[5]; a[0] = 3; a[1] = 4; a[2] = 1; a[3] = 5; a[4] = 2; // 插 入 法 排 序 int temp; for (int i = 1; i < a.length; i++) { // i=1 开 始, 因 为 第 一 个 元 素 认 为 是 已 经 排 好 序 了 的 for (int j = i; (j > 0) && (a[j] < a[j - 1]); j--) { // 交 换 temp = a[j]; a[j] = a[j - 1]; a[j - 1] = temp; 第 122 页

123 // 检 测 一 下 排 序 的 结 果 for (int i : a) { System.out.println("i=" + i); 运 行 结 果 : i=1 i=2 i=3 i=4 i=5 如 果 你 想 要 按 照 降 序 排 列, 很 简 单, 只 需 要 把 :if (a[j] <a[lowindex]) 这 句 话 修 改 成 : if (a[j] > a[lowindex]) 就 可 以 了 希 尔 (Shell) 法 排 序 从 前 面 介 绍 的 冒 泡 排 序 法, 选 择 排 序 法, 插 入 排 序 法 可 以 发 现, 如 果 数 据 已 经 大 致 排 好 序 的 时 候, 其 交 换 数 据 位 置 的 动 作 将 会 减 少 例 如 在 插 入 排 序 法 过 程 中, 如 果 某 一 整 数 d[i] 不 是 较 小 时, 则 其 往 前 比 较 和 交 换 的 次 数 会 更 少 如 何 用 简 单 的 方 式 让 某 些 数 据 有 一 定 的 大 小 次 序 呢? Donald Shell(Shell 排 序 的 创 始 人 ) 提 出 了 希 尔 法 排 序 基 本 思 路 : 先 将 数 据 按 照 固 定 的 间 隔 分 组, 例 如 每 隔 4 个 分 成 一 组, 然 后 排 序 各 分 组 的 数 据, 形 成 以 分 组 来 看 数 据 已 经 排 序, 从 全 部 数 据 来 看, 较 小 值 已 经 在 前 面, 较 大 值 已 经 在 后 面 将 初 步 处 理 了 的 分 组 再 用 插 入 排 序 来 排 序, 那 么 数 据 交 换 和 移 动 的 次 数 会 减 少 可 以 得 到 比 插 入 排 序 法 更 高 的 效 率 示 例 如 下 : public class Test { public static void main(string[] args) { // 需 要 排 序 的 数 组, 按 照 升 序 排 列 int a[] = new int[5]; a[0] = 3; a[1] = 4; a[2] = 1; a[3] = 5; a[4] = 2; // shell 法 排 序 int j = 0; int temp = 0; // 分 组 for(int increment = a.length / 2; increment > 0; increment /= 2) { // 每 个 组 内 排 序 for (int i = increment; i < a.length; i++) { 第 123 页

124 temp = a[i]; for (j = i; j >= increment; j -= increment) { if (temp < a[j - increment]) { a[j] = a[j - increment]; else { break; a[j] = temp; // 检 测 一 下 排 序 的 结 果 for (int i2 : a) { System.out.println("i=" + i2); 运 行 结 果 : i=1 i=2 i=3 i=4 i=5 如 果 你 想 要 按 照 降 序 排 列, 很 简 单, 只 需 要 把 :if (temp < a[j - increment]) 这 句 话 修 改 成 :if (temp > a[j - increment]) 就 可 以 了 数 组 排 序 事 实 上, 数 组 的 排 序 不 用 那 么 麻 烦, 上 面 只 是 想 让 大 家 对 一 些 基 本 的 排 序 算 法 有 所 了 解 而 已 在 java.util.arrays 类 中 有 一 个 静 态 方 法 sort, 可 以 用 这 个 类 的 sort 方 法 来 对 数 组 进 行 排 序 示 例 如 下 : public class Test { public static void main(string[] args) { // 需 要 排 序 的 数 组, 目 前 是 按 照 升 序 排 列 的 int a[] = new int[5]; a[0] = 3; a[1] = 4; a[2] = 1; a[3] = 5; a[4] = 2; // 数 组 排 序 java.util.arrays.sort(a); // 检 测 一 下 排 序 的 结 果 for (int i2 : a) { System.out.println("i=" + i2); 第 124 页

125 注 意 : 现 在 的 sort 方 法 都 是 升 序 的, 要 想 实 现 降 序 的, 还 需 要 Comparator 的 知 识, 这 个 在 后 面 会 学 到 5.6 数 组 实 用 类 Arrays 在 java.util 包 中, 有 一 个 用 于 操 纵 数 组 的 实 用 类 Arrays 它 提 供 了 一 系 列 静 态 方 法, 帮 助 开 发 人 员 操 作 数 组 public static boolean equals( 数 组 参 数 1, 数 组 参 数 2) 比 较 两 个 数 组 参 数 是 否 相 同, 数 组 参 数 可 以 是 基 本 数 据 类 型, 也 可 以 是 引 用 数 据 类 型 只 有 当 两 个 数 组 中 的 元 素 数 目 相 同, 并 且 对 应 位 置 的 元 素 也 相 同 时, 才 表 示 数 组 相 同 如 果 是 引 用 类 型 的 数 组, 比 较 的 是 引 用 类 型 的 equals 方 法 示 例 如 下 : String[] a1={"java 快 车 ","javakc","javakc"; String[] a2={"java 快 车 ","javakc","javakc"; System.out.print(Arrays.equals(a1, a2)); 运 行 结 果 :true public static void fill( 数 组, 数 据 参 数 ) 向 数 组 中 填 充 数 据 参 数, 把 数 组 中 所 有 元 素 的 值 设 置 为 该 数 据 数 组 和 数 据 参 数 的 类 型 必 须 一 致, 或 可 以 自 动 转 化, 数 组 和 元 素 可 以 是 基 本 数 据 类 型, 也 可 以 是 引 用 数 据 类 型 示 例 如 下 : // 基 本 数 据 类 型 或 字 符 串 String[] arr=new String[5]; Arrays.fill(arr, "Java 快 车 "); for(string s:arr){ System.out.print(s+","); // 引 用 数 据 类 型, 使 用 了 同 一 个 引 用 A[] arr2=new A[5]; Arrays.fill(arr2, new A()); for(a a:arr2){ System.out.print(a+","); 运 行 结 果 如 下 : Java 快 车,Java 快 车,Java 快 车,Java 快 车,Java 快 车, A@5224ee,A@5224ee,A@5224ee,A@5224ee,A@5224ee, public static void fill( 数 组,int fromindex, int toindex, 数 据 参 数 ) 向 数 组 中 指 定 的 范 围 填 充 数 据 参 数, 此 范 围 包 含 fromindex, 但 不 包 含 toindex 数 组 和 数 据 参 数 的 类 型 必 须 一 致, 或 可 以 自 动 转 化, 数 组 和 元 素 可 以 是 基 本 数 据 类 型, 也 可 以 是 引 用 数 据 类 型 示 例 如 下 : 第 125 页

126 String[] arr=new String[5]; Arrays.fill(arr,1,3,"Java 快 车 "); for(string s:arr){ System.out.print(s+","); 运 行 结 果 如 下 : null,java 快 车,Java 快 车,null,null, public static int binarysearch( 数 组, 数 据 参 数 ) 查 找 数 组 中 元 素 的 值 与 给 定 数 据 相 同 的 元 素 数 组 和 数 据 参 数 的 类 型 必 须 一 致, 或 可 以 自 动 转 化, 数 组 和 数 据 参 数 可 以 是 基 本 数 据 类 型, 也 可 以 是 引 用 数 据 类 型 因 为 此 方 法 采 用 二 分 法 进 行 查 找 数 据, 所 以 当 调 用 该 方 法 时, 必 须 保 证 数 组 中 的 元 素 已 经 按 照 升 序 排 列, 这 样 才 能 得 到 正 确 的 结 果 如 果 该 数 组 包 含 此 数 据 参 数, 则 返 回 对 应 的 数 组 下 标, 否 则 返 回 一 个 负 数 示 例 如 下 : int[] arr={2,4,6,7,9,10,20; System.out.print(Arrays.binarySearch(arr, 9)); 运 行 结 果 :4 int[] arr={2,4,6,7,9,10,20; System.out.print(Arrays.binarySearch(arr, 8)); 运 行 结 果 :-6 public static int binarysearch( 数 组,int fromindex,int toindex, 数 据 参 数 ) 在 数 组 中 指 定 的 范 围 查 找 元 素 的 值 与 给 定 数 据 相 同 的 元 素 其 他 说 明 如 上 示 例 如 下 : double[] arr={2,4,6,7,9,10,20; System.out.print(Arrays.binarySearch(arr,1,5,10)); 运 行 结 果 :-6 public static void sort( 数 组 ) 把 数 组 中 的 数 组 按 升 序 排 列 数 组 可 以 是 基 本 数 据 类 型, 也 可 以 是 引 用 数 据 类 型 public static void copyof( 数 组,int newlength) 赋 值 指 定 的 数 组, 截 取 下 标 0( 包 括 ) 至 newlength( 不 包 括 ) 范 围 示 例 如 下 : int[] arr={2,4,6,7,9,10,20; int[] arr2=arrays.copyof(arr, 4); for(int i:arr2){ System.out.print(i+","); 运 行 结 果 :2,4,6,7, public static 数 组 copyofrange( 数 组,int from,int to) 将 数 组 的 指 定 范 围 复 制 到 一 个 新 数 组 数 组 可 以 是 基 本 数 据 类 型, 也 可 以 是 引 用 数 据 类 型 第 126 页

127 示 例 如 下 : int[] arr={2,4,6,7,9,10,20; int[] arr2=arrays.copyofrange(arr,1,5); for(int i:arr2){ System.out.print(i+","); 运 行 结 果 :4,6,7,9, public static String tostring( 数 组 ) 返 回 指 定 数 组 内 容 的 字 符 串 表 示 形 式 数 组 可 以 是 基 本 数 据 类 型, 也 可 以 是 引 用 数 据 类 型 示 例 如 下 : int[] arr={2,4,6,7,9,10,20; System.out.print(Arrays.toString(arr)); 运 行 结 果 :[2, 4, 6, 7, 9, 10, 20] 5.7 枚 举 类 型 ( 可 选 ) 什 么 是 枚 举 类 型 枚 举 类 型 enum 是 一 种 新 的 类 型, 在 JDK5.0 加 入, 允 许 用 常 量 来 表 示 特 定 的 数 据 片 断, 这 些 数 据 是 分 配 时 预 先 定 义 的 值 的 集 合, 而 且 全 部 都 以 类 型 安 全 的 形 式 来 表 示 在 枚 举 类 型 没 有 加 入 到 Java 前, 我 们 要 想 表 达 常 量 的 集 合, 通 常 采 用 如 下 的 方 式 : public class Test { public static final int A = 1; public static final int B = 2; public static final int C = 3; public static final int D = 4; public static final int E = 5; 那 么 我 们 在 使 用 的 时 候 就 采 用 如 下 代 码 : Test.A 或 者 Test.B 之 类 的 代 码 但 是 在 这 样 做 的 时 候, 我 们 需 要 记 住 这 类 常 量 是 Java 中 int 类 型 的 常 量, 这 意 味 着 该 方 法 可 以 接 受 任 何 int 类 型 的 值, 即 使 它 和 Test 中 定 义 的 所 有 级 别 都 不 对 应 因 此 需 要 检 测 上 界 和 下 界, 在 出 现 无 效 值 的 时 候, 可 能 还 要 包 含 一 个 IllegalArgumentException 而 且, 如 果 后 来 又 添 加 另 外 一 个 级 别 ( 例 如 TEST.F, 那 么 必 须 改 变 所 有 代 码 中 的 上 界, 才 能 接 受 这 个 新 值 换 句 话 说, 在 使 用 这 类 带 有 整 型 常 量 的 类 时, 该 解 决 方 案 也 许 可 行, 但 并 不 是 非 常 有 效 第 127 页

128 枚 举 就 为 处 理 上 述 问 题 提 供 了 更 好 的 方 法 把 上 面 的 例 子 改 成 用 枚 举 的 方 式 : public class Test { public enum StudentGrade { A, B, C, D, E, F ; 可 以 采 用 如 下 的 方 式 进 行 使 用 : public class Test { public enum StudentGrade { A, B, C, D, E, F ; public static void main(string[] args) { System.out.println(" 学 生 的 平 均 成 绩 为 ==" + StudentGrade.B); 上 面 的 示 例 都 相 当 简 单, 但 是 枚 举 类 型 提 供 的 东 西 远 不 止 这 些 您 可 以 逐 个 遍 历 枚 举 值, 也 可 以 在 switch 语 句 中 使 用 枚 举 值, 枚 举 是 非 常 有 价 值 的 遍 历 枚 举 类 型 示 例 如 下 : public class Test { public enum StudentGrade { A, B, C, D, E, F ; public static void main(string[] args) { for (StudentGrade score : StudentGrade.values()) { System.out.println(" 学 生 成 绩 取 值 可 以 为 ==" + score); 运 行 结 果 : 学 生 成 绩 取 值 可 以 为 ==A 学 生 成 绩 取 值 可 以 为 ==B 学 生 成 绩 取 值 可 以 为 ==C 学 生 成 绩 取 值 可 以 为 ==D 学 生 成 绩 取 值 可 以 为 ==E 学 生 成 绩 取 值 可 以 为 ==F values() 方 法 返 回 了 一 个 由 独 立 的 StudentGrade 实 例 构 成 的 数 组 还 有 一 个 常 用 的 方 法 :valueof(string): 功 能 是 以 字 符 串 的 形 式 返 回 某 一 个 具 体 枚 举 元 素 的 值, 示 例 如 下 : public class Test { public enum StudentGrade { 第 128 页

129 A, B, C, D, E, F ; public static void main(string[] args) { Test t = new Test(); StudentGrade score = StudentGrade.valueOf("A"); System.out.println(" 你 的 成 绩 是 :" + score); 运 行 结 果 : 你 的 成 绩 是 :A 在 switch 中 使 用 枚 举 类 型 示 例 如 下 : public class Test { public enum StudentGrade { A, B, C, D, E, F ; public static void main(string[] args) { Test t = new Test(); StudentGrade score = StudentGrade.C; switch (score) { case A: System.out.println(" 你 的 成 绩 是 优 秀 "); break; case B: System.out.println(" 你 的 成 绩 是 好 "); break; case C: System.out.println(" 你 的 成 绩 是 良 "); break; case D: System.out.println(" 你 的 成 绩 是 及 格 "); break; default: System.out.println(" 你 的 成 绩 是 不 及 格 "); break; 运 行 结 果 : 你 的 成 绩 是 良 在 这 里, 枚 举 值 被 传 递 到 switch 语 句 中, 而 每 个 case 子 句 将 处 理 一 个 特 定 的 值 该 值 在 提 供 时 没 有 枚 举 前 缀, 这 意 味 着 不 用 将 代 码 写 成 case StudentGrade.A, 只 需 将 其 写 成 case A 即 可, 编 译 器 不 会 接 受 有 前 缀 的 值 第 129 页

130 5.7.4 枚 举 类 型 的 特 点 从 上 面 的 示 例 中 可 以 看 出, 枚 举 类 型 大 概 有 如 下 特 点 : 类 型 安 全 紧 凑 有 效 的 枚 举 数 值 定 义 运 行 的 高 效 率 类 型 安 全 枚 举 的 申 明 创 建 了 一 个 新 的 类 型 它 不 同 于 其 它 的 已 有 类 型, 包 括 原 始 类 型 ( 整 数, 浮 点 数 等 等 ) 和 当 前 作 用 域 (Scope) 内 的 其 它 的 枚 举 类 型 当 你 对 方 法 的 参 数 进 行 赋 值 操 作 的 时 候, 整 数 类 型 和 枚 举 类 型 是 不 能 互 换 的 ( 除 非 是 你 进 行 显 式 的 类 型 转 换 ), 编 译 器 将 强 制 这 一 点 比 如 说, 用 上 面 申 明 的 枚 举 定 义 这 样 一 个 方 法 : public void foo(day); 如 果 你 用 整 数 来 调 用 这 个 函 数, 编 译 器 会 给 出 错 误 的 必 须 用 这 个 类 型 的 值 进 行 调 用 foo(4); // compilation error 比 较 前 面 写 的 例 子, 你 看 看 是 枚 举 定 义 写 得 紧 凑, 还 是 直 接 使 用 static final 紧 凑 呢 答 案 是 不 言 而 喻 的 枚 举 的 运 行 效 率 和 原 始 类 型 的 整 数 类 型 基 本 上 一 样 高 在 运 行 时 不 会 由 于 使 用 了 枚 举 而 导 致 性 能 有 所 下 降 第 130 页

131 5.8 学 习 目 标 1. 熟 练 使 用 一 维 数 组 的 声 明 创 建 初 始 化 访 问 2. 了 解 一 维 数 组 的 内 存 分 配, 能 画 出 内 存 分 配 图 3. 会 用 for 循 环 访 问 一 维 数 组 4. 熟 练 使 用 二 维 数 组 的 声 明 创 建 初 始 化 访 问 5. 描 述 多 维 数 组 的 本 质 :n 维 数 组 是 一 维 的 n-1 维 6. 了 解 二 维 数 组 的 内 存 分 配, 能 画 出 内 存 分 配 图 7. 会 用 嵌 套 for 循 环 访 问 二 维 数 组 8. 能 画 出 引 用 数 据 类 型 的 数 组 的 内 存 分 配 图 9. 如 何 完 成 数 组 的 复 制 10. 了 解 冒 泡 排 序 选 择 排 序 插 入 排 序 希 尔 排 序 算 法, 最 少 能 默 写 出 其 中 一 种 排 序 算 法 11. 熟 练 掌 握 Arrays 工 具 类 中 的 方 法 能 说 出 大 部 分 方 法 的 方 法 名 称 完 成 的 功 能, 甚 至 参 数 列 表 返 回 值 类 型 抛 出 的 异 常 第 131 页

132 5.9 练 习 1. 写 一 个 方 法, 在 方 法 内 部 定 义 一 个 一 维 的 int 数 组, 然 后 为 这 个 数 组 赋 上 初 始 值, 最 后 再 循 环 取 值 并 打 印 出 来 2. 下 面 的 数 组 定 义 那 些 是 正 确 的? A. int a[ ][ ] = new int[3,3]; B. int a[3][3] = new int[ ][ ]; C. int a[ ][ ] = new int[3][3]; D. int [ ]a[ ] = new int[3][3]; E. int [ ][ ]a = new int[3][3]; 3. 定 义 一 个 长 度 为 10 的 一 维 字 符 串 数 组, 在 每 一 个 元 素 存 放 一 个 单 词 ; 然 后 运 行 时 从 命 令 行 输 入 一 个 单 词, 程 序 判 断 数 组 是 否 包 含 有 这 个 单 词, 包 含 这 个 单 词 就 打 印 出 Yes, 不 包 含 就 打 印 出 No 4. 请 在 下 面 语 句 中 找 出 一 个 正 确 的 A. int arr1[2][3]; B. int[ ][ ] a2 = new int[2][ ]; C. int[ ][ ] arr2 = new int [ ][4]; D. int arr3[ ][4] = new int [3][4]; 5. 用 二 重 循 环 求 出 二 维 数 组 b 所 有 元 素 的 和 : int[ ][ ] b={{11,{21,22,{31,32,33 6. 编 写 一 个 方 法 实 现 将 班 级 同 学 的 名 单 存 放 在 数 组 中, 并 利 用 随 机 数 (Math.random()) 随 机 输 出 一 位 同 学 的 姓 名 7. 生 成 一 百 个 随 机 数, 放 到 数 组 中, 然 后 排 序 输 出 8. 统 计 字 符 串 中 英 文 字 母 空 格 数 字 和 其 它 字 符 的 个 数 提 示 :String 类 中 有 一 个 tochararray 方 法, 可 以 将 此 字 符 串 转 换 成 一 个 char 类 型 的 数 组, 另 外 还 需 要 用 到 asc 码 第 132 页

133 6 常 见 类 的 使 用 在 java 中 有 成 百 上 千 的 类, 每 个 类 又 有 很 多 不 同 的 方 法, 要 记 住 所 有 的 类 和 方 法 是 不 可 能 的 因 此, 熟 练 掌 握 如 何 查 阅 API 是 相 当 重 要 的 从 中 可 以 查 到 标 准 库 中 所 有 的 类 及 方 法 Api 文 档 是 Java SDK 的 一 部 分, 它 以 HTML 形 式 发 布 Api 的 主 页 面 有 三 个 窗 口 组 成 左 上 端 的 窗 口 列 出 了 所 有 可 以 利 用 的 包, 坐 下 端 是 所 有 可 用 的 类, 如 果 点 击 一 个 类 名, 关 于 这 个 Api 的 文 档 将 会 显 示 在 右 边 最 大 的 窗 格 关 于 类 的 声 明 属 性 构 造 方 法 成 员 方 法 及 其 他 们 的 说 明 文 字 都 在 这 个 大 窗 口 打 开 下 面 我 们 介 绍 几 个 在 Java 中 常 用 的 类 6.1 Object 类 java.lang 包 中 定 义 的 Object 类 是 所 有 Java 类 的 根 父 类, 其 中 定 义 了 一 些 实 现 和 支 持 面 向 对 象 机 制 的 重 要 方 法 任 何 Java 对 象, 如 果 没 有 父 类, 就 默 认 它 继 承 了 Object 类 因 此, 实 际 上, 以 前 的 定 义 是 下 面 的 简 略 : public class Employee extends Object public class Manager extends Employee Object 类 定 义 许 多 有 用 的 方 法, 包 括 tostring(), 它 就 是 为 什 么 Java 软 件 中 每 样 东 西 都 能 转 换 成 字 符 串 表 示 法 的 原 因 ( 即 使 这 仅 具 有 有 限 的 用 途 ) equals 方 法 Object 类 定 义 的 equals 方 法 用 于 判 别 某 个 指 定 的 对 象 与 当 前 对 象 ( 调 用 equals 方 法 第 133 页

134 的 对 象 ) 是 否 等 价 在 Java 语 言 中 数 据 等 价 的 基 本 含 义 是 指 两 个 数 据 的 值 相 等 在 equals 和 == 进 行 比 较 的 时 候, 引 用 类 型 数 据 比 较 的 是 引 用, 即 内 存 地 址, 基 本 数 据 类 型 比 较 的 是 值 equals 方 法 与 == 运 算 符 的 关 系 equals() 方 法 只 能 比 较 引 用 类 型, == 可 以 比 较 引 用 类 型 及 基 本 类 型 ; 特 例 : 当 用 equals() 方 法 进 行 比 较 时, 对 类 File String Date 及 包 装 类 来 说, 是 比 较 类 型 及 内 容 而 不 考 虑 引 用 的 是 否 是 同 一 个 实 例 ; 用 == 进 行 比 较 时, 符 号 两 边 的 数 据 类 型 必 须 一 致 ( 可 自 动 转 换 的 数 据 类 型 除 外 ), 否 则 编 译 出 错, 而 用 equals 方 法 比 较 的 两 个 数 据 只 要 都 是 引 用 类 型 即 可 示 例 如 下 : class MyDate { private int day, month, year; public MyDate(int day, int month, int year) { this.day = day; this.month = month; this.year = year; public class Test { public static void main(string[] args) { MyDate m1 = new MyDate(8, 8, 2008); MyDate m2 = new MyDate(8, 8, 2008); if (m1 == m2) { System.out.println("m1==m2"); else { System.out.println("m1!=m2"); if (m1.equals(m2)) { System.out.println("m1 is equal to m2"); else { System.out.println("m1 is not equal to m2"); m2 = m1; if (m1 == m2) { System.out.println("m1==m2"); else { System.out.println("m1!=m2"); 第 134 页

135 程 序 运 行 结 果 为 : m1!=m2 m1 is not equal to m2 m==m2 小 结 一 下 : 在 引 用 类 型 的 比 较 上,Object 里 面 的 equals 方 法 默 认 的 比 较 方 式, 基 本 上 等 同 于 ==, 都 是 比 较 内 存 地 址, 只 有 那 几 个 特 殊 的 是 比 较 的 值 覆 盖 equals 方 法 对 于 程 序 员 来 说, 如 果 一 个 对 象 需 要 调 用 equals 方 法, 应 该 在 类 中 覆 盖 equals 方 法 如 果 覆 盖 了 equals 方 法, 那 么 具 体 的 比 较 就 按 照 你 的 实 现 进 行 比 较 了 一 般 来 讲 : 为 了 比 较 两 个 分 离 的 对 象 ( 也 就 是 内 存 地 址 不 同 的 两 个 对 象 ), 自 行 覆 盖 的 equals 方 法 里 面 都 是 检 查 类 型 和 值 是 否 相 同 上 面 那 几 个 特 殊 的 情 况 就 是 这 样, 比 如 String 类, 它 覆 盖 了 equals 方 法, 然 后 在 里 面 进 行 值 的 比 较 覆 盖 equals 方 法 的 一 般 步 骤 如 下 : (1) 用 == 检 查 是 否 参 数 就 是 这 个 对 象 的 引 用 (2) 判 断 要 比 较 的 对 象 是 否 为 null, 如 果 是 null, 返 回 false (3) 用 instanceof 判 断 参 数 的 类 型 是 否 正 确 (4) 把 参 数 转 换 成 合 适 的 类 型 (5) 比 较 对 象 属 性 值 是 不 是 匹 配 示 例 如 下 : 覆 盖 前 equals 和 == 比 较 的 都 是 内 存 地 址 : public class Test { public static void main(string[] args) { A a1 = new A(); a1.id = 3; A a2 = new A(); a2.id = 3; System.out.println("a1 == a2 test =" + (a1 == a2)); System.out.println("a1 equals a2 test =" + a1.equals(a2)); class A { public int id = 0; 第 135 页

136 运 行 结 果 是 : a1== a2 test =false a1 equals a2 test =false 覆 盖 后 equals 比 较 的 是 值,== 比 较 的 是 内 存 地 址 : public class Test { public static void main(string[] args) { Test t = new Test(); A a1 = new A(); a1.id = 3; A a2 = new A(); a2.id = 3; System.out.println("a1 == a2 test =" + (a1 == a2)); System.out.println("a1 equals a2 test =" + a1.equals(a2)); class A { public int id = 0; public boolean equals(object obj) { // 第 一 步 先 判 断 是 否 同 一 个 实 例 if (this == obj) { return true; // 第 二 步 判 断 要 比 较 的 对 象 是 否 为 null if (obj == null) { return false; // 第 三 步 判 断 是 否 同 一 个 类 型 if (obj instanceof A) { // 第 四 步 类 型 相 同, 先 转 换 成 为 同 一 个 类 型 A a = (A) obj; // 第 五 步 然 后 进 行 对 象 属 性 值 的 比 较 if (this.id == a.id) { return true; else { return false; else { // 类 型 不 同, 直 接 返 回 false return false; 说 明 : 如 果 对 象 的 属 性 又 是 一 个 引 用 类 型 的 话, 会 继 续 调 用 该 引 用 类 型 的 equals 方 法, 直 到 最 后 得 出 相 同 还 是 不 同 的 结 果 示 例 如 下 : public class Test { public static void main(string[] args) { 第 136 页

137 Test t = new Test(); A a1 = new A(); a1.id = 3; A a2 = new A(); a2.id = 3; System.out.println("a1 == a2 test =" + (a1 == a2)); System.out.println("a1 equals a2 test =" + a1.equals(a2)); class A { public int id = 0; public String name = "Java 快 车 "; public boolean equals(object obj) { // 第 一 步 先 判 断 是 否 同 一 个 实 例 if (this == obj) { return true; // 第 二 步 判 断 要 比 较 的 对 象 是 否 为 null if (obj == null) { return false; // 第 三 步 判 断 是 否 同 一 个 类 型 if (obj instanceof A) { // 第 四 步 类 型 相 同, 先 转 换 成 为 同 一 个 类 型 A a = (A) obj; // 第 五 步 然 后 进 行 对 象 属 性 值 的 比 较 if (this.id == a.id && this.name.equals(a.name)) { return true; else { return false; else { // 类 型 不 同, 直 接 返 回 false return false; 最 后 重 要 的 一 点 规 则 : 覆 盖 equals 方 法 应 该 连 带 覆 盖 hashcode 方 法 hashcode 方 法 hashcode 是 按 照 一 定 的 算 法 得 到 的 一 个 数 值, 是 对 象 的 散 列 码 值 主 要 用 来 在 集 合 ( 后 面 会 学 到 ) 中 实 现 快 速 查 找 等 操 作, 也 可 以 用 于 对 象 的 比 较 在 Java 中, 对 hashcode 的 规 定 如 下 : (1) 在 同 一 个 应 用 程 序 执 行 期 间, 对 同 一 个 对 象 调 用 hashcode(), 必 须 返 回 相 同 的 整 数 第 137 页

138 结 果 前 提 是 equals() 所 比 较 的 信 息 都 不 曾 被 改 动 过 至 于 同 一 个 应 用 程 序 在 不 同 执 行 期 所 得 的 调 用 结 果, 无 需 一 致 ( 2 ) 如 果 两 个 对 象 被 equals(object) 方 法 视 为 相 等, 那 么 对 这 两 个 对 象 调 用 hashcode() 必 须 获 得 相 同 的 整 数 结 果 (3) 如 果 两 个 对 象 被 equals(object) 方 法 视 为 不 相 等, 那 么 对 这 两 个 对 象 调 用 hashcode() 不 必 产 生 不 同 的 整 数 结 果 然 而 程 序 员 应 该 意 识 到, 对 不 同 对 象 产 生 不 同 的 整 数 结 果, 有 可 能 提 升 hashtable( 后 面 会 学 到, 集 合 框 架 中 的 一 个 类 ) 的 效 率 简 单 地 说 : 如 果 两 个 对 象 相 同, 那 么 它 们 的 hashcode 值 一 定 要 相 同 ; 如 果 两 个 对 象 的 hashcode 相 同, 它 们 并 不 一 定 相 同 在 Java 规 范 里 面 规 定, 覆 盖 equals 方 法 应 该 连 带 覆 盖 hashcode 方 法, 这 就 涉 及 到 一 个 如 何 实 现 hashcode 方 法 的 问 题 了 实 现 一 : 偷 懒 的 做 法 : 对 同 一 对 象 始 终 返 回 相 同 的 hashcode, 如 下 : public int hashcode() { return 1; 它 是 合 法 的, 但 是 不 好, 因 为 每 个 对 象 具 有 相 同 的 hashcode, 会 使 得 很 多 使 用 hashcode 的 类 的 运 行 效 率 大 大 降 低, 甚 至 发 生 错 误 实 现 二 : 采 用 一 定 的 算 法 来 保 证 在 高 效 Java 编 程 这 本 书 里 面, 给 大 家 介 绍 了 一 个 算 法, 现 在 eclipse 自 动 生 成 equals 方 法 和 hashcode 方 法 就 是 用 的 这 个 算 法, 下 面 介 绍 一 下 这 个 算 法 : (1) 将 一 个 非 0 常 数, 例 如 31, 储 存 于 int result 变 量 (2) 对 对 象 中 的 每 个 有 意 义 的 属 性 f( 更 确 切 的 说 是 被 equals() 所 考 虑 的 每 一 个 属 性 ) 进 行 如 下 处 理 : A. 对 这 个 属 性 计 算 出 类 型 为 int 的 hash 码 c: 如 果 属 性 是 个 boolean, 计 算 (f? 0 : 1) 如 果 属 性 是 个 byte,char,short 或 int, 计 算 (int)f 如 果 属 性 是 个 long, 计 算 (int)(f ^ (f >>> 32)) 如 果 属 性 是 个 float, 计 算 Float.floatToIntBits(f) 如 果 属 性 是 个 double, 计 算 Double.doubleToLongBits(f), 然 后 将 计 算 结 果 按 步 骤 2.A.iii 处 理 第 138 页

139 如 果 属 性 是 个 对 象 引 用, 而 且 class 的 equals() 通 过 递 归 调 用 equals() 的 方 式 来 比 较 这 一 属 性, 那 么 就 同 样 也 对 该 属 性 递 归 调 用 hashcode() 如 果 需 要 更 复 杂 的 比 较, 请 对 该 属 性 运 算 一 个 范 式 (canonical representation), 并 对 该 范 式 调 用 hashcode() 如 果 属 性 值 是 null, 就 返 回 0( 或 其 它 常 数 ; 返 回 0 是 传 统 做 法 ) 如 果 属 性 是 个 数 组, 请 将 每 个 元 素 视 为 独 立 属 性 也 就 是 说 对 每 一 个 有 意 义 的 元 素 施 行 上 述 规 则, 用 以 计 算 出 hash 码, 然 后 再 依 步 骤 2.B 将 这 些 数 值 组 合 起 来 B. 将 步 骤 A 计 算 出 来 的 hash 码 c 按 下 列 公 式 组 合 到 变 量 result 中 : result = 31*result + c; (3) 返 回 result 示 例 如 下 : 这 个 就 是 用 eclipse 自 动 生 成 的 import java.util.arrays; public class Test { private byte bytevalue; private char charvalue; private short shortvalue; private int intvalue; private long longvalue; private boolean booleanvalue; private float floatvalue; private double doublevalue; private String uuid; private int[] intarray = new int[3]; public int hashcode() { final int prime = 31; int result = 1; result = prime * result + (booleanvalue? 1231 : 1237); result = prime * result + charvalue; long temp; temp = Double.doubleToLongBits(doubleValue); result = prime * result + (int) (temp ^ (temp >>> 32)); result = prime * result + Float.floatToIntBits(floatValue); result = prime * result + Arrays.hashCode(intArray); result = prime * result + intvalue; result = prime * result + (int) (longvalue ^ (longvalue >>> 32)); result = prime * result + shortvalue; result = prime * result + ((uuid == null)? 0 : uuid.hashcode()); return result; 第 139 页

140 6.1.3 tostring 方 法 tostring() 方 法 是 Object 类 中 定 义 的 另 一 个 重 要 方 法, 是 对 象 的 字 符 串 表 现 形 式, 其 格 式 为 : public String tostring(){ 方 法 的 返 回 值 是 String 类 型, 用 于 描 述 当 前 对 象 的 有 关 信 息 Object 类 中 实 现 的 tostring() 方 法 是 返 回 当 前 对 象 的 类 型 和 内 存 地 址 信 息, 但 在 一 些 子 类 ( 如 String, Date 等 ) 中 进 行 了 重 写, 也 可 以 根 据 需 要 在 用 户 自 定 义 类 型 中 重 写 tostring() 方 法, 以 返 回 更 适 用 的 信 息 除 显 式 调 用 对 象 的 tostring() 方 法 外, 在 进 行 String 与 其 它 类 型 数 据 的 连 接 操 作 时, 会 自 动 调 用 tostring() 方 法, 其 中 又 分 为 两 种 情 况 : (1) 引 用 类 型 数 据 直 接 调 用 其 tostring() 方 法 转 换 为 String 类 型 ; (2) 基 本 类 型 数 据 先 转 换 为 对 应 的 包 装 类 型, 再 调 用 该 包 装 类 的 tostring() 方 法 转 换 为 String 类 型 另 外, 在 System.out.println() 方 法 输 出 引 用 类 型 的 数 据 时, 也 先 自 动 调 用 了 该 对 象 的 tostring() 方 法, 然 后 再 将 返 回 的 字 符 串 输 出 示 例 如 下 : class MyDate { private int day, month, year; public MyDate(int d, int m, int y) { day = d; month = m; year = y; class YourDate { private int day, month, year; public YourDate(int d, int m, int y) { day = d; month = m; year = y; public String tostring() { return day + "-" + month + "-" + year; public class Test { public static void main(string args[]) { MyDate m = new MyDate(8, 8, 2008); System.out.println(m); 第 140 页

141 System.out.println(m.toString()); YourDate y = new YourDate(8, 8, 2008); System.out.println(y); 运 行 结 果 : cn.javadriver.java6.test.mydate@1fb8ee3 cn.javadriver.java6.test.mydate@1fb8ee tostring 方 法 被 用 来 将 一 个 对 象 转 换 成 String 表 达 式 当 自 动 字 符 串 转 换 发 生 时, 它 被 用 作 编 译 程 序 的 参 照 System.out.println() 调 用 下 述 代 码 : Date now = new Date() ; System.out.println(now); // 将 被 翻 译 成 : System.out.println(now.toString()); 对 象 类 定 义 缺 省 的 tostring() 方 法, 它 返 回 类 名 称 和 它 的 引 用 的 地 址 ( 通 常 情 况 下 不 是 很 有 用 ) 许 多 类 覆 盖 tostring() 以 提 供 更 有 用 的 信 息 例 如, 所 有 的 包 装 类 覆 盖 tostring() 以 提 供 它 们 所 代 表 的 值 的 字 符 串 格 式 甚 至 没 有 字 符 串 格 式 的 类 为 了 调 试 目 的 常 常 实 现 tostring() 来 返 回 对 象 状 态 信 息 6.2 String 类 String 的 声 明 和 创 建 双 引 号 括 起 来 的 字 符 序 列 就 是 String 的 直 接 量 实 例 :"John" 或 " " 字 符 串 赋 值, 可 以 在 声 明 时 赋 值 : String color = "blue"; color 是 String 类 型 的 引 用 "blue" 是 String 直 接 量 String 类 型 的 数 据 存 在 String 常 量 池 ( 栈 内 存 ) 中, 一 旦 定 义 值 就 不 能 改 变, 只 能 是 让 变 量 指 向 新 的 内 存 空 间 比 如 : color = "red"; 如 果 采 用 new 的 方 法 定 义 String, 那 么 是 需 要 分 配 堆 内 存 空 间 的, 如 下 : String str = new String("Hello"); 一 共 有 两 个 对 象, 在 栈 和 堆 内 存 中 各 有 一 个 对 象, 内 容 都 是 "Hello" String 的 还 有 两 个 常 用 的 构 造 方 法 : 第 141 页

142 String(byte[] arr) 使 用 一 个 字 节 数 组 arr 创 建 一 个 字 符 串 对 象 String(char[] arr) 使 用 一 个 字 符 数 组 arr 创 建 一 个 字 符 串 对 象 char[] arr={'h','e','l','l','o'; String str = new String(arr); // 相 当 于 String str = new String("Hello"); String(char[] arr,int startindex,int count) 提 取 字 符 数 组 a 中 的 一 部 分 字 符 创 建 一 个 字 符 串 对 象, 参 数 startindex 和 count 分 别 指 定 在 a 中 提 取 字 符 的 起 始 位 置 和 从 该 位 置 开 始 截 取 的 字 符 个 数, 例 如 : char[] arr={'h','e','l','l','o'; String str = new String(arr,1,3); // 相 当 于 String str = new String("ell"); String 的 常 用 方 法 得 到 字 符 串 的 长 度 public int length() 返 回 String 的 长 度, 是 按 照 char 返 回 的 长 度 与 数 组 不 同 之 处 : String 类 不 含 有 length 成 员 域 ( 属 性 ) String str = "java 快 车 System.out.println(str.length());// 比 较 字 符 串 对 于 字 符 串, 使 用 == 比 较 的 是 内 存 地 址, 一 般 不 使 用 == 比 较 字 符 串 public boolean equals(object s) 比 较 两 个 String 对 象 的 实 体 是 否 相 等, 这 个 是 区 分 大 小 写 的 实 际 上 就 是 依 次 比 较 其 所 包 含 的 字 符 的 数 值 大 小 String s1= new String("java 快 车 "); String s2= new String("java 快 车 "); System.out.println(s1.equals(s2));//true public boolean equalsignorecase(string s) 比 较 两 个 String 对 象 的 值 是 否 相 等, 忽 略 大 小 写 第 142 页

143 String s1= new String("java 快 车 "); String s2= new String("JAVA 快 车 "); System.out.println(s1.equalsIgnoreCase(s2));//true public int compareto(string s) 比 较 两 个 字 符 串 的 大 小 返 回 0 表 示 相 等, 返 回 大 于 0 的 数 表 示 前 面 的 字 符 串 大 于 后 面 的 字 符 串, 返 回 小 于 0 表 示 前 面 的 字 符 串 小 于 后 面 的 字 符 串, 区 分 大 小 写 的 如 下 : public class Test { public static void main(string[] args) { int x="abc".compareto("abc"); System.out.println(x);//0 x="bbc".compareto("abc"); System.out.println(x);//1 int x="abc".compareto("bbc"); System.out.println(x);//-1 int x="cbc".compareto("abc"); System.out.println(x);//2 运 行 结 果 : the str 小 于 str2 public int comparetoignorecase(string s) 忽 略 大 小 写, 比 较 两 个 字 符 串 的 大 小 返 回 0 表 示 相 等, 返 回 大 于 0 的 数 表 示 前 面 的 字 符 串 大 于 后 面 的 字 符 串, 返 回 小 于 0 表 示 前 面 的 字 符 串 小 于 后 面 的 字 符 串 如 下 : public class Test { public static void main(string[] args) { int x="abc".comparetoignorecase("abc"); System.out.println(x);//0 运 行 结 果 :the str 等 于 str2 public boolean startswith(stirng prefix) 测 试 此 字 符 串 是 否 以 指 定 的 前 缀 开 始 第 143 页

144 public class Test { public static void main(string[] args) { String str = " 这 里 是 Java 快 车 "; String str2 = "Java"; System.out.println(str.startsWith(str2)); 运 行 结 果 :false public boolean startswith(string prefix,int toffset) 测 试 此 字 符 串 从 指 定 索 引 开 始 的 子 字 符 串 是 否 以 指 定 前 缀 开 始 public class Test { public static void main(string[] args) { String str = " 这 里 是 Java 快 车 "; String str2 = "Java"; System.out.println(str.startsWith(str2, 3)); 运 行 结 果 :true public boolean endswith(string suffix) 测 试 此 字 符 串 是 否 以 指 定 的 后 缀 结 束 public class Test { public static void main(string[] args) { String str = " 这 里 是 Java 快 车 "; String str2 = " 快 车 "; System.out.println(str.endsWith(str2)); 运 行 结 果 :true 字 符 串 检 索 public char charat(int index) 获 得 字 符 串 指 定 位 置 的 字 符 String s="javakc"; // 取 得 字 符 串 s 中 下 标 为 2 的 字 符 char c=s.charat(2); System.out.println(c);// 输 出 'v' 第 144 页

145 // 取 得 字 符 串 s 中 下 标 为 6 的 字 符 char c2=s.charat(6); System.out.println(c2);// 抛 出 StringIndexOutOfBoundsException 异 常 public int indexof(int ch) 返 回 指 定 字 符 ch 在 此 字 符 串 中 第 一 次 出 现 处 的 索 引 String name="cooltools"; System.out.println(name.indexOf('T'));//4 public int indexof(string str) 返 回 第 一 次 找 到 字 符 串 str 时 的 索 引, 如 果 没 有 找 到, 则 返 回 -1 实 例 : String name="cooltools"; System.out.println(name.indexOf("oo"));//1 System.out.println(name.indexOf("kc"));//-1 public int indexof(int ch,int fromindex) 从 指 定 的 索 引 开 始 搜 索, 返 回 在 此 字 符 串 中 第 一 次 出 现 指 定 字 符 处 的 索 引, 如 果 没 有 找 到, 则 返 回 -1 String name="cooltools"; System.out.println(name.indxOf('l',5));//7 public int indexof(string str,int fromindex) 指 定 的 索 引 开 始 搜 索, 返 回 在 此 字 符 串 中 第 一 次 出 现 指 定 字 符 串 处 的 索 引, 如 果 没 有 找 到, 则 返 回 -1 String name="cooltools"; System.out.println(name.indexOf("oo",3));//5 public int lastindexof(string str) 返 回 指 定 子 字 符 串 在 此 字 符 串 中 最 右 边 出 现 处 的 索 引 laseindexof 有 四 中 重 载 方 法, 用 法 和 indexof 相 似 截 取 字 符 串 public String substring(int beginindex) 返 回 新 的 字 符 串, 它 是 当 前 字 符 串 的 子 串 该 子 串 从 指 定 的 位 置 开 始, 并 一 直 到 当 前 字 符 串 结 束 为 止 第 145 页

146 public String substring(int beginindex,int endindex) 返 回 新 的 字 符 串, 它 是 当 前 字 符 串 的 子 串 该 子 串 从 指 定 的 位 置 (beginindex ) 开 始, 到 指 定 的 位 置 (endindex - 1) 结 束 例 如 : "unhappy".substring(2); // 返 回 "happy" "Harbison".substring(3); // 返 回 "bison" "emptiness".substring(9); // 返 回 ""( 空 串 ) "emptiness".substring(10); // 返 回 StringIndexOutOfBoundsException "hamburger".substring(4,8); // 返 回 "urge" "smiles".substring(1,5); // 返 回 "mile" 替 换 public String trim() 返 回 新 字 符 串, 截 去 了 源 字 符 串 最 前 面 和 最 后 面 的 的 空 白 符 ; 如 果 字 符 串 没 有 被 改 变, 则 返 回 源 字 符 串 的 引 用 String s=" java kc "; // 截 去 字 符 串 两 边 的 空 格 String s2=s.trim(); System.out.println(s2.length());//7 public String replace(char oldchar,char newchar) public String replace(charsequence target, CharSequence replacement) 返 回 一 个 新 的 字 符 串, 它 是 将 字 符 串 中 的 所 有 oldchar 替 换 成 newchar 源 字 符 串 没 有 发 生 变 化 如 果 该 字 符 串 不 含 oldchar, 则 返 回 源 字 符 串 的 引 用 实 例 : "mesquite in your cellar".replace('e','o');// 返 回 "mosquito in your collar" "JonL".replace('q','x'); // 结 果 返 回 "JonL" ( 没 有 发 生 变 化 ) 示 例 将 字 符 串 中 所 有 空 格 删 除 : String s=" java kc "; // 将 全 部 空 格 替 换 成 空 字 符 串, 即 将 所 有 空 格 删 除 String s2=s.replace(" ", ""); System.out.println(s2);// 输 出 javakc public String replaceall(string regex, String replacement) 使 用 给 定 的 replacement 替 换 此 字 符 串 中 所 有 匹 配 给 定 的 正 则 表 达 式 的 子 字 符 串 源 字 符 串 没 有 发 生 变 化 第 146 页

147 如 果 该 字 符 串 不 含 regex, 则 返 回 源 字 符 串 的 引 用 String s="javakc35javakc36javakc37"; // 将 数 字 全 部 换 成 * 号 String s2=s.replaceall("\\d","*");// \\d 在 正 则 表 达 式 中 表 示 数 字 System.out.println(s2);// 输 出 javakc**javakc**javakc** public String touppercase( ) 返 回 对 应 的 新 字 符 串, 所 有 小 写 字 母 都 变 为 大 写 的, 其 它 的 不 变 如 果 没 有 字 符 被 修 改, 则 返 回 字 符 串 的 引 用 String s="javakc"; // 小 写 转 换 成 大 写 String s2=s.touppercase(); System.out.println(s2);// 输 出 JAVAKC public String tolowercase() 返 回 对 应 的 新 字 符 串, 所 有 大 写 字 母 都 变 为 小 写 的, 其 它 的 不 变 如 果 没 有 字 符 被 修 改, 则 返 回 字 符 串 的 引 用 String s="javakc"; // 大 写 转 换 成 小 写 String s2=s.tolowercase(); System.out.println(s2);// 输 出 javakc 字 符 串 分 解 成 数 组 public byte[] getbytes() 组 中 使 用 平 台 的 默 认 字 符 集 将 此 String 编 码 为 byte 序 列, 并 将 结 果 存 储 到 一 个 新 的 byte 数 String s="javakc 快 车 "; // 将 字 符 串 转 换 成 字 节 数 组 byte[] a=s.getbytes(); // 输 出 [106, 97, 118, 97, 75, 67, -65, -20, -77, -75] System.out.println(Arrays.toString(a)); // 将 字 节 数 组 转 换 成 字 符 串 String s2=new String(a); System.out.println(s2);// 输 出 javakc 快 车 对 于 字 符 串 中 的 汉 字, 是 按 照 char 来 计 算 的, 一 个 中 文 汉 字 占 两 个 字 节, 也 就 是 说, 通 过 length() 得 到 的 是 字 符 串 char 的 长 度, 而 不 是 字 节 数, 利 用 这 个 特 点, 就 可 以 进 行 中 文 判 断 了 例 如 : 如 何 判 断 一 个 字 符 串 里 面 有 没 有 中 文 呢? 如 果 字 符 串 对 应 的 byte[] 和 char[] 的 长 第 147 页

148 度 是 不 一 样 的, 那 就 说 明 包 含 中 文, 还 可 以 顺 带 计 算 出 有 几 个 汉 字 public class Test { public static void main(string[] args) { String str = " 欢 迎 来 到 Java 快 车 "; int charlen = str.length(); int bytelen = str.getbytes().length; if (bytelen > charlen) { int chinesenum = bytelen - charlen; System.out.println("str 包 含 汉 字, 汉 字 共 " + chinesenum + " 个 "); else { System.out.println("str 没 有 包 含 汉 字 "); 运 行 结 果 是 :str 包 含 汉 字, 汉 字 共 6 个 public void getchars(int srcbegin,intsrcend, char[] dst,int dstbegin) 拷 贝 字 符 串 的 部 分 字 符 序 列 到 指 定 的 字 符 数 组 的 指 定 位 置 ; 要 复 制 的 第 一 个 字 符 位 于 索 引 srcbegin 处 ; 要 复 制 的 最 后 一 个 字 符 位 于 索 引 srcend-1 处 ( 因 此 要 复 制 的 字 符 总 数 是 srcend-srcbegin) 要 复 制 到 dst 子 数 组 的 字 符 从 索 引 dstbegin 处 开 始, 并 结 束 于 索 引 char[] arr={'1','2','3','4','5','6'; String s= "collection"; s.getchars(4, 7, arr, 2); for(char c:arr){ System.out.print(c+","); 执 行 结 果 :1,2,e,c,t,6, public char[] tochararray() 将 此 字 符 串 转 换 为 一 个 新 的 字 符 数 组 String s="java 快 车 "; // 将 字 符 串 转 换 成 字 符 数 组 char[] b=s.tochararray(); System.out.println(Arrays.toString(b));// 输 出 [j, a, v, a, 快, 车 ] // 将 字 符 数 组 转 换 成 字 符 串 String s2=new String(b); System.out.println(s2);// 输 出 java 快 车 第 148 页

149 public String[] split(string regex) 根 据 给 定 正 则 表 达 式 的 匹 配 拆 分 此 字 符 串, 得 到 拆 分 好 的 字 符 串 数 组, 示 例 如 下 : public class Test { public static void main(string[] args) { String str = " 这 里, 是 Java, 快 车 "; String temps[] = str.split(",");// 按 照 "," 对 字 符 串 进 行 拆 分 for (int i = 0; i < temps.length; i++) { System.out.println("tempS[" + i + "]===" + temps[i]); 运 行 结 果 : temps[0]=== 这 里 temps[1]=== 是 Java temps[2]=== 快 车 注 意 : 因 为. 和 都 是 转 义 字 符, 必 须 得 加 \\ (1) 如 果 用. 作 为 分 隔 的 话, 必 须 是 如 下 写 法 :String.split("\\."), 这 样 才 能 正 确 的 分 隔 开, 不 能 用 String.split("."); public class Test { public static void main(string[] args) { String str = " 这 里. 是 Java. 快 车 "; String temps[] = str.split("\\.");// 按 照 "." 对 字 符 串 进 行 拆 分 for (int i = 0; i < temps.length; i++) { System.out.println("tempS[" + i + "]===" + temps[i]); (2) 如 果 用 作 为 分 隔 的 话, 必 须 是 如 下 写 法 :String.split("\\ "), 这 样 才 能 正 确 的 分 隔 开, 不 能 用 String.split(" "); public class Test { public static void main(string[] args) { String str = " 这 里 是 Java 快 车 "; String temps[] = str.split("\\ ");// 按 照 " " 对 字 符 串 进 行 拆 分 for (int i = 0; i < temps.length; i++) { System.out.println("tempS[" + i + "]===" + temps[i]); 展 示 字 符 串 public String concat(string str) 拼 接 两 个 字 符 串, 并 返 回 一 个 新 字 符 串 源 字 符 串 不 会 被 修 改 s1.concat( s2 ) 返 回 字 符 串 s1 和 s2 拼 接 的 结 果 第 149 页

150 String s1 = "javakc"; String s2 = "37"; s1 = s1.concat(s2); // 等 同 于 s1 = s1 + s2; public static String valueof( 参 数 列 表 ) 将 参 数 的 值 转 化 成 相 应 的 字 符 串 // 将 数 字 转 换 成 字 符 串 String s=string.valueof(37); // 也 可 以 这 样 转 成 字 符 串 String s2=37+""; public static String valueof(char[] data) 返 回 new String(data); char[] a={'j','a','v','a','k','c','3','7'; String s=string.valueof(a); System.out.println(s);// 输 出 javakc37 public static String valueof(char[] data, int offset,int count) 返 回 new String(data,offset,count); char[] a={'j','a','v','a','k','c','3','7'; String s=string.valueof(a,4,4); System.out.println(s);// 输 出 kc37 public String tostring( ) 由 于 源 对 象 就 是 字 符 串 了, 所 以 返 回 字 符 串 本 身 其 它 引 用 类 型 也 可 以 通 过 重 写 方 法 tostring, 生 成 相 应 的 字 符 串 ( 详 见 Object 的 tostring 方 法 ) 6.3 正 则 表 达 式 和 相 关 的 String 方 法 完 整 的 正 则 表 达 式 语 法 是 比 较 复 杂 的, 这 里 只 是 简 单 地 入 个 门, 更 多 的 正 则 表 达 式 请 参 考 相 应 的 书 籍 或 者 文 章 不 过 没 有 什 么 大 的 必 要, 常 见 的 正 则 表 达 式 基 本 都 是 写 好 了 的, 拿 过 来 用 就 可 以 了 第 150 页

151 6.3.1 什 么 是 正 则 表 达 式 在 编 写 处 理 字 符 串 的 程 序 时, 经 常 会 有 查 找 符 合 某 些 复 杂 规 则 的 字 符 串 的 需 要, 正 则 表 达 式 就 是 用 于 描 述 这 些 规 则 的 工 具 换 句 话 说, 正 则 表 达 式 就 是 记 录 文 本 规 则 的 代 码 回 忆 一 下 在 Windows 下 进 行 文 件 查 找, 查 找 的 通 配 符 也 就 是 * 和? 如 果 你 想 查 找 某 个 目 录 下 的 所 有 的 Word 文 档 的 话, 你 会 搜 索 *.doc 在 这 里,* 会 被 解 释 成 任 意 的 字 符 串 和 通 配 符 类 似, 正 则 表 达 式 也 是 用 来 进 行 文 本 匹 配 的 工 具, 只 不 过 比 起 通 配 符, 它 能 更 精 确 地 描 述 你 的 需 求 当 然, 代 价 就 是 更 复 杂 比 如 你 可 以 编 写 一 个 正 则 表 达 式, 用 来 查 找 所 有 以 0 开 头, 后 面 跟 着 2-3 个 数 字, 然 后 是 一 个 连 字 号 -, 最 后 是 7 或 8 位 数 字 的 字 符 串 ( 像 或 ) 简 言 之 正 则 表 达 式 是 用 于 进 行 文 本 匹 配 的 工 具, 也 是 一 个 匹 配 的 表 达 式 正 则 表 达 式 基 础 入 门 学 习 正 则 表 达 式 的 最 好 方 法 是 从 例 子 开 始, 理 解 例 子 之 后 再 自 己 对 例 子 进 行 修 改, 实 验 下 面 给 出 了 不 少 简 单 的 例 子, 并 对 它 们 作 了 详 细 的 说 明 假 设 你 在 一 篇 英 文 小 说 里 查 找 hi, 你 可 以 使 用 正 则 表 达 式 hi 这 是 最 简 单 的 正 则 表 达 式 了, 它 可 以 精 确 匹 配 这 样 的 字 符 串 : 由 两 个 字 符 组 成, 前 一 个 字 符 是 h, 后 一 个 是 i 通 常, 处 理 正 则 表 达 式 的 工 具 会 提 供 一 个 忽 略 大 小 写 的 选 项, 如 果 选 中 了 这 个 选 项, 它 可 以 匹 配 hi,hi,hi,hi 这 四 种 情 况 中 的 任 意 一 种 不 幸 的 是, 很 多 单 词 里 包 含 hi 这 两 个 连 续 的 字 符, 比 如 him,history,high 等 等 用 hi 来 查 找 的 话, 这 里 边 的 hi 也 会 被 找 出 来 如 果 要 精 确 地 查 找 hi 这 个 单 词 的 话, 我 们 应 该 使 用 \bhi\b \b 是 正 则 表 达 式 规 定 的 一 个 特 殊 代 码 ( 某 些 人 叫 它 元 字 符,meta character), 代 表 着 单 词 的 开 头 或 结 尾, 也 就 是 单 词 的 分 界 处 虽 然 通 常 英 文 的 单 词 是 由 空 格 或 标 点 符 号 或 换 行 来 分 隔 的, 但 是 \b 并 不 匹 配 这 些 单 词 分 隔 符 中 的 任 何 一 个, 它 只 匹 配 一 个 位 置 假 如 你 要 找 的 是 hi 后 面 不 远 处 跟 着 一 个 Lucy, 你 应 该 用 \bhi\b.*\blucy\b. 是 另 一 个 元 字 符, 匹 配 除 了 换 行 符 以 外 的 任 意 字 符 * 同 样 是 元 字 符, 不 过 它 代 表 的 不 是 字 符, 也 不 是 位 置, 而 是 数 量 它 指 定 * 前 边 的 内 容 可 以 连 续 重 复 出 现 任 意 次 以 使 整 个 表 达 式 得 到 匹 配 因 此,.* 连 在 一 起 就 意 味 着 任 意 数 量 的 不 包 含 换 行 符 现 在 \bhi\b.*\blucy\b 的 意 思 就 很 明 显 了 : 先 是 一 个 单 词 hi, 然 后 是 任 意 个 任 意 字 符 ( 但 不 能 是 换 行 符 ), 最 后 是 Lucy 这 个 单 词 例 子 : 如 果 同 时 使 用 其 它 的 一 些 元 字 符, 我 们 就 能 构 造 出 功 能 更 强 大 的 正 则 表 达 式 比 如 下 面 这 个 0\d\d-\d\d\d\d\d\d\d\d 匹 配 这 样 的 字 符 串 : 以 0 开 头, 然 后 是 两 个 数 字, 然 后 是 一 个 连 字 号 -, 最 后 是 8 个 数 字 ( 也 就 是 中 国 的 电 话 号 码 当 然, 这 个 例 子 只 能 匹 配 区 号 为 3 位 的 情 形 ) 第 151 页

152 这 里 的 \d 是 一 个 新 的 元 字 符, 匹 配 任 意 的 数 字 (0, 或 1, 或 2, 或 ) - 不 是 元 字 符, 只 匹 配 它 本 身 连 字 号 为 了 避 免 那 么 多 烦 人 的 重 复, 我 们 也 可 以 这 样 写 这 个 表 达 式 :0\d{2-\d{8 这 里 \d 后 面 的 {2 和 {8 的 意 思 是 前 面 \d 必 须 连 续 重 复 匹 配 2 次 和 8 次 在 Java 中 运 行 正 则 表 达 式 在 Java 中 的 String 类 中 有 好 几 个 方 法 都 跟 正 则 表 达 式 有 关, 最 典 型 的 就 是 public boolean matches(string regex) 判 断 此 字 符 是 否 匹 配 给 定 的 正 则 表 达 式 使 用 这 个 方 法 来 测 试 和 运 行 上 面 学 到 的 正 则 表 达 式, 示 例 如 下 : public class Test { public static void main(string[] args) { String str = " "; System.out.println("str 是 一 个 正 确 的 电 话 号 码? 答 案 是 :" + str.matches("0\\d{2-\\d{8")); 运 行 结 果 :str 是 一 个 正 确 的 电 话 号 码? 答 案 是 :true 注 意 : 由 于 在 Java 里 面 \ 需 要 转 义, 应 该 变 成 \\ 在 Java 中, 有 专 门 进 行 正 则 表 达 式 的 类, 在 java.util.regex 包 里 面 java.util.regex.pattern 类 Pattern 类 是 正 则 表 达 式 的 编 译 表 示 形 式 指 定 为 字 符 串 的 正 则 表 达 式 必 须 首 先 被 编 译 为 此 类 的 实 例 然 后, 可 将 得 到 的 模 式 用 于 创 建 Matcher 对 象, 依 照 正 则 表 达 式, 该 对 象 可 以 与 任 意 字 符 序 列 匹 配 执 行 匹 配 所 涉 及 的 所 有 状 态 都 驻 留 在 匹 配 器 中, 所 以 多 个 匹 配 器 可 以 共 享 同 一 模 式 常 见 方 法 如 下 : static Pattern compile(string expression) static Pattern compile(string expression, int flags): 编 译 正 则 表 达 式 字 符 串 到 pattern 对 象 用 以 匹 配 的 快 速 处 理 参 数 : expression 正 则 表 达 式 flags 下 列 标 志 中 的 一 个 或 多 个 : CASE_INSENSITIVE,UNICODE_CASE,MULTILINE,UNIX_LINES,DOTALL,and 第 152 页

153 CANON_EQ Matcher matcher(charsequence input) 返 回 一 个 matcher 对 象, 它 可 以 用 来 在 一 个 输 入 中 定 位 模 式 匹 配 String[] split(charsequence input) String[] split(charsequence input, int limit) 将 输 入 字 符 串 分 离 成 记 号, 并 由 pattern 来 指 定 分 隔 符 的 形 式 返 回 记 号 数 组 分 隔 符 并 不 是 记 号 的 一 部 分 参 数 : input 分 离 成 记 号 的 字 符 串 limit 生 成 的 最 大 字 符 串 数 java.util.regex.matcher 类 Mathcer 类 通 过 解 释 Pattern 对 字 符 序 列 执 行 匹 配 操 作 的 引 擎 常 见 方 法 如 下 : boolean matches(): 返 回 输 入 是 否 与 模 式 匹 配 boolean lookingat(): 如 果 输 入 的 起 始 匹 配 模 式 则 返 回 True boolean find() boolean find(int start): 尝 试 查 找 下 一 个 匹 配, 并 在 找 到 匹 配 时 返 回 True 参 数 : start 开 始 搜 索 的 索 引 int start(): 返 回 当 前 匹 配 的 起 始 位 置 位 置 int end(): 返 回 当 前 匹 配 的 结 尾 后 位 置 String group(): 返 回 当 前 匹 配 int groupcount(): 返 回 输 入 模 式 中 的 分 组 数 int start(int groupindex) int end(int groupindex) 返 回 一 个 给 定 分 组 当 前 匹 配 中 的 起 始 位 置 和 结 尾 后 位 置 参 数 : groupindex 分 组 索 引 ( 从 1 开 始 ),0 表 示 整 个 匹 配 第 153 页

154 String group(int groupindex): 返 回 匹 配 一 个 给 定 分 组 的 字 符 串 参 数 : groupindex 分 组 索 引 ( 从 1 开 始 ),0 表 示 整 个 匹 配 String replaceall(string replacement) String replacefirst(string replacement) 返 回 从 matcher 输 入 得 到 的 字 符 串, 但 已 经 用 替 换 表 达 式 替 换 所 有 或 第 一 个 匹 配 参 数 : replacement 替 换 字 符 串 Matcher reset() Matcher reset(charsequence input) 复 位 mather 状 态 Java 中 操 作 正 则 表 达 式 示 例 public class Test { public static void main(string[] args) { String str = " "; Pattern p = Pattern.compile("0\\d{2-\\d{8"); Matcher m = p.matcher(str); boolean flag = m.matches(); System.out.println("str 是 一 个 正 确 的 电 话 号 码? 答 案 是 :" + flag); 运 行 结 果 :str 是 一 个 正 确 的 电 话 号 码? 答 案 是 :true 元 字 符 现 在 你 已 经 知 道 几 个 很 有 用 的 元 字 符 了, 如 \b. *, 还 有 \d. 当 然 还 有 更 多 的 元 字 符 可 用, 比 如 \s 匹 配 任 意 的 空 白 符, 包 括 空 格, 制 表 符 (Tab), 换 行 符, 中 文 全 角 空 格 等 \w 匹 配 字 母 或 数 字 或 下 划 线 等 常 用 的 元 字 符 代 码 说 明. 匹 配 除 换 行 符 以 外 的 任 意 字 符 \w 匹 配 字 符 或 数 字 或 下 划 线 \s 匹 配 任 意 的 空 白 符 \d 匹 配 数 字 \b 匹 配 字 符 串 的 开 始 或 结 束 ^ 匹 配 字 符 串 的 开 始 $ 匹 配 字 符 串 的 结 束 第 154 页

155 下 面 来 试 试 更 多 的 例 子 : 例 1:\ba\w*\b 匹 配 以 字 母 a 开 头 的 单 词 先 是 某 个 单 词 开 始 处 (\b), 然 后 是 字 母 a, 然 后 是 任 意 数 量 的 字 母 或 数 字 (\w*), 最 后 是 单 词 结 束 处 (\b)( 好 吧, 现 在 我 们 说 说 正 则 表 达 式 里 的 单 词 是 什 么 意 思 吧 : 就 是 几 个 连 续 的 \w 不 错, 这 与 学 习 英 文 时 要 背 的 成 千 上 万 个 同 名 的 东 西 的 确 关 系 不 大 ) 例 2:\d+ 匹 配 1 个 或 更 多 连 续 的 数 字 这 里 的 + 是 和 * 类 似 的 元 字 符, 不 同 的 是 * 匹 配 重 复 任 意 次 ( 可 能 是 0 次 ), 而 + 则 匹 配 重 复 1 次 或 更 多 次 例 3:\b\w{6\b 匹 配 刚 好 6 个 字 母 / 数 字 的 单 词 例 4:^\d{5,12$ 匹 配 必 须 为 5 位 到 12 位 数 字 的 字 符 串 元 字 符 ^( 和 数 字 6 在 同 一 个 键 位 上 的 符 号 ) 以 及 $ 和 \b 有 点 类 似, 都 匹 配 一 个 位 置 ^ 匹 配 你 要 用 来 查 找 的 字 符 串 的 开 头,$ 匹 配 结 尾 这 两 个 代 码 在 验 证 输 入 的 内 容 时 非 常 有 用, 比 如 一 个 网 站 如 果 要 求 你 填 写 的 QQ 号 时, 可 以 使 用 这 里 的 {5,12 和 前 面 介 绍 过 的 {2 是 类 似 的, 只 不 过 {2 匹 配 只 能 不 多 不 少 重 复 2 次, {5,12 则 是 重 复 的 次 数 不 能 少 于 5 次, 不 能 多 于 12 次, 否 则 都 不 匹 配 因 为 使 用 了 ^ 和 $, 所 以 输 入 的 整 个 字 符 串 都 要 用 来 和 \d{5,12 来 匹 配, 也 就 是 说 整 个 输 入 必 须 是 5 到 12 个 数 字, 因 此 如 果 输 入 的 QQ 号 能 匹 配 这 个 正 则 表 达 式 的 话, 那 就 符 合 要 求 了 重 复 已 经 看 过 了 前 面 的 *,+,{2,{5,12 这 几 个 匹 配 重 复 的 方 式 了 下 面 是 正 则 表 达 式 中 所 有 的 限 定 符 ( 指 定 数 量 的 代 码, 例 如 *,{5,12 等 ): 常 用 的 限 定 符 代 码 / 语 法 说 明 * 重 复 零 次 或 多 次 + 重 复 一 次 或 多 次? 重 复 零 次 或 一 次 {n 重 复 n 次 {n, 重 复 n 次 或 更 多 次 {n,m 重 复 n 次 到 m 次 下 面 是 一 些 使 用 重 复 的 例 子 : Windows\d+ 匹 配 Windows 后 面 跟 1 个 或 更 多 数 字 第 155 页

156 13\d{9 匹 配 13 后 面 跟 9 个 数 字 ( 中 国 的 手 机 号 ) 字 符 类 要 想 查 找 数 字, 字 母 或 数 字, 空 白 是 很 简 单 的, 因 为 已 经 有 了 对 应 这 些 字 符 集 合 的 元 字 符, 但 是 如 果 你 想 匹 配 没 有 预 定 义 元 字 符 的 字 符 集 合 ( 比 如 元 音 字 母 a,e,i,o,u), 应 该 怎 么 办? 很 简 单, 你 只 需 要 在 中 括 号 里 列 出 它 们 就 行 了, 像 [aeiou] 就 匹 配 任 何 一 个 英 文 元 音 字 母, [.?!] 匹 配 标 点 符 号 (. 或? 或!)( 英 文 语 句 通 常 只 以 这 三 个 标 点 结 束 ) 我 们 也 可 以 轻 松 地 指 定 一 个 字 符 范 围, 像 [0-9] 代 表 的 含 意 与 \d 就 是 完 全 一 致 的 : 一 位 数 字, 同 理 [a-z0-9a-z_] 也 完 全 等 同 于 \w( 如 果 只 考 虑 英 文 的 话 ) 常 见 正 则 表 达 式 (1) 检 测 是 否 地 址 ^([\\w-\\.]+)@((\\[[0-9]{1,3\\.[0-9]{1,3\\.[0-9]{1,3\\.) (([\\w- ]+\\.)+))([a-za-z]{2,4 [0-9]{1,3)(\\]?)$ (2) 判 断 输 入 的 字 符 串 只 包 含 汉 字 ^[\u4e00-\u9fa5]+$ (3) 匹 配 3 位 或 4 位 区 号 的 电 话 号 码, 其 中 区 号 可 以 用 小 括 号 括 起 来, 也 可 以 不 用, 区 号 与 本 地 号 间 可 以 用 连 字 号 或 空 格 间 隔, 也 可 以 没 有 间 隔 ^\\(0\\d{2\\)[-]?\\d{8$ ^0\\d{2[-]?\\d{8$ ^\\(0\\d{3\\)[-]?\\d {7$ ^0\\d{3[-]?\\d{7$ (4) 判 断 输 入 的 字 符 串 是 否 是 一 个 合 法 的 手 机 号, 这 个 不 完 全, 只 是 13 开 头 的 ^1[3,5,8]\\d{9$ (5) 判 断 输 入 的 字 符 串 只 包 含 数 字, 可 以 匹 配 整 数 和 浮 点 数 ^-?\\d+$ ^(-?\\d+)(\\.\\d+)?$ (6) 匹 配 非 负 整 数, 最 多 9 位 数 ^\\d [1-9]+\\d{2,9$ (7) 判 断 输 入 的 字 符 串 只 包 含 英 文 字 母 ^[A-Za-z]+$ (8) 判 断 输 入 的 字 符 串 是 否 只 包 含 数 字 和 英 文 字 母 ^[A-Za-z0-9]+$ 好 了, 学 到 这 里 对 基 本 的 正 则 表 达 式 就 有 了 基 本 的 认 识, 下 面 来 看 看 String 里 面 跟 正 则 表 达 式 有 关 的 几 个 方 法 的 使 用 第 156 页

157 6.4 StringBuffer 类 和 StringBuilder 类 前 面 学 到 过 String 类 有 一 个 重 要 的 特 点, 那 就 是 String 的 值 是 不 可 变 的, 这 就 导 致 每 次 对 String 的 操 作 都 会 生 成 新 的 String 对 象, 不 仅 效 率 低 下, 而 且 大 量 浪 费 有 限 的 内 存 空 间 那 么 对 于 经 常 要 改 变 值 的 字 符 串 应 该 怎 样 操 作 呢? 答 案 就 是 使 用 StringBuffer 和 StringBuilder 类, 这 两 个 类 功 能 基 本 相 似, 区 别 主 要 在 于 StringBuffer 类 的 方 法 是 多 线 程 安 全 的 ( 多 线 程 的 课 程 在 后 面 会 学 习 到 ), 而 StringBuilder 不 是 线 程 安 全 的, 相 比 而 言 StringBuilder 类 会 略 微 快 一 点 StringBuffer 类 String 字 符 串 (String) 对 象 一 旦 创 建, 其 内 容 不 能 再 被 修 改 (read-only) StringBuffer StringBuffer 对 象 的 内 容 是 可 以 被 修 改 的 除 了 字 符 的 长 度 之 外, 还 有 容 量 的 概 念 通 过 动 态 改 变 容 量 的 大 小, 加 速 字 符 管 理 StringBuffer 的 构 造 方 法 StringBuffer buf1 = new StringBuffer(); 创 建 空 的 StringBuffer 对 象, 初 始 容 量 为 16 字 符 StringBuffer buf2 = new StringBuffer( 容 量 ); 创 建 空 的 StringBuffer 对 象, 指 定 容 量 大 小 StringBuffer buf3 = new StringBuffer( mystring ); 创 建 含 有 相 应 字 符 序 列 的 StringBuffer 对 象, 容 量 为 mystring.length() StringBuffer 的 常 用 方 法 public int length() 返 回 StringBuffer 的 长 度 public int capacity() 返 回 StringBuffer 的 容 量 public void setlength(int newlength) 第 157 页

158 增 加 或 减 小 StringBuffer 的 长 度 public char charat(int index) 返 回 StringBuffer 对 象 中 指 定 位 置 的 字 符 public void setcharat(int index, char ch) 设 置 StringBuffer 对 象 中 指 定 位 置 的 字 符 public void getchars(int srcbegin, int srcend,char[] dst, int dstbegin) 将 StringBuffer 对 象 中 指 定 的 字 符 子 序 列, 拷 贝 到 指 定 的 字 符 数 组 (dst) public void reverse() 将 StringBuffer 对 象 中 的 字 符 序 列 按 逆 序 方 式 排 列, 可 用 作 字 符 串 倒 序 public StringBuffer append( ) 允 许 数 值 类 型 的 值 添 加 到 StringBuffer 对 象 中 public StringBuffer insert( ) 允 许 将 各 种 数 据 插 到 StringBuffer 对 象 的 指 定 位 置 public StringBuffer delete(int start, int end) public StringBuffer deletecharat(int index) 允 许 删 除 StringBuffer 对 象 中 的 指 定 字 符 其 中 最 常 用 的 恐 怕 就 要 算 append 方 法 和 tostring 方 法 了, 如 下 示 例 : public class Test { public static void main(string[] args) { StringBuffer buffer = new StringBuffer(); buffer.append(" 这 里 "); buffer.append(" 是 "); buffer.append("java"); buffer.append(" 快 车 "); System.out.println("buffer==" + buffer.tostring()); 运 行 结 果 :buffer== 这 里 是 Java 快 车 StringBuilder 类 StringBuilder 类 是 一 个 可 变 的 字 符 序 列 此 类 提 供 一 个 与 StringBuffer 兼 容 的 API, 但 不 保 证 同 步 该 类 被 设 计 用 作 StringBuffer 的 一 个 简 易 替 换, 用 在 字 符 串 缓 冲 区 被 单 个 线 程 使 用 的 时 候 ( 这 种 情 况 很 普 遍 ) 如 果 可 能, 建 议 优 先 采 用 该 类, 因 为 在 大 多 数 实 现 中, 它 比 StringBuffer 要 快 它 的 功 能 基 本 等 同 于 StringBuffer 类, 就 不 再 赘 述 了 public class Test { 第 158 页

159 public static void main(string[] args) { StringBuilder builder = new StringBuilder(); builder.append(" 这 里 "); builder.append(" 是 "); builder.append("java"); builder.append(" 快 车 "); System.out.println("buffer==" + builder.tostring()); 运 行 结 果 :builder== 这 里 是 Java 快 车 6.5 Math 类 Java 中 的 数 学 (Math) 类 是 final 类, 不 可 继 承 其 中 包 含 一 组 静 态 方 法 和 两 个 常 数 常 数 PI :double, 圆 周 率 E :double, 自 然 对 数 方 法 截 取 注 意 方 法 的 返 回 类 型 public static double ceil(double d) 返 回 不 小 于 d 的 最 小 整 数 double d=math.ceil(8.7); System.out.println(d);// 输 出 9.0 double d2=math.ceil(-8.7); System.out.println(d2); // 输 出 -8.0 public static double floor(double d) 返 回 不 大 于 d 的 最 大 整 数 double d=math.floor(8.7); System.out.println(d);// 输 出 8.0 double d2=math.floor(-8.7); System.out.println(d2); // 输 出 -9.0 第 159 页

160 public static int round(float f) 返 回 四 舍 五 入 后 的 整 数 int n=math.round(8.7f); System.out.println(n);// 输 出 9 int m=math.round(-8.7f); System.out.println(m);// 输 出 -9 public static long round(double d) 返 回 四 舍 五 入 后 的 整 数 long lon=math.round(8.7); System.out.println(lon);// 输 出 9 long lon2=math.round(-8.7); System.out.println(lon2);// 输 出 变 换 public static double abs(double d) 返 回 绝 对 值 int i=math.abs(10); System.out.println(i);// 输 出 10 int j=math.abs(-10); System.out.println(j);// 输 出 10 public static double min(double d1, double d2) 返 回 两 个 值 中 较 小 的 值 int i=math.min(10,20); System.out.println(i);// 输 出 10 double d=math.min(3.5,6.7); System.out.println(d);// 输 出 3.5 public static double max(double d1, double d2) 返 回 两 个 值 中 较 大 的 值 int i=math.max(10,20); System.out.println(i);// 输 出 20 double d=math.max(3.5,6.7); System.out.println(d);// 输 6.7 第 160 页

161 对 数 public static double log(double d) 自 然 对 数 public static double exp(double d) E 的 指 数 其 它 public static double sqrt(double d) 返 回 平 方 根 double d=math.sqrt(4); System.out.println(d);// 输 出 2.0 double d2=math.sqrt(5); System.out.println(d2);// 输 出 public static double random() 返 回 随 机 数 double d=math.random(); System.out.println(d);// 输 出 double d2=math.random(); System.out.println(d2);// 输 出 还 有 三 角 函 数 的 运 算 等, 请 参 考 JDK 文 档 示 例 如 下 : 问 题 : 请 问 有 101 条 记 录, 按 照 每 组 10 条 记 录 进 行 分 组, 应 该 分 多 少 组? public class Test { public static void main(string[] args) { int records = 101;// 共 有 101 条 记 录 final int GROUP_NUM = 10;// 每 组 10 条 int groups = (int) Math.ceil(1.0 * records / GROUP_NUM); // 注 意 这 里 的 1.0, 目 的 是 要 把 类 型 变 成 double 型 的, 而 不 是 int, 结 果 还 是 int, 就 错 了 System.out.println(" 应 该 分 的 组 数 为 =" + groups); 运 行 结 果 : 应 该 分 的 组 数 为 11 第 161 页

162 6.6 日 期 操 作 的 类 Date 类 java.util 包 里 面 的 Date 类, 是 Java 里 面 进 行 日 期 操 作 常 用 类 Date 类 用 来 表 示 特 定 的 瞬 间, 精 确 到 毫 秒 初 始 化 Date Date 的 构 造 方 法 : public Date( ) 分 配 Date 对 象 并 初 始 化 此 对 象, 以 表 示 分 配 它 的 时 候 的 当 前 时 间 ( 精 确 到 毫 秒 ) 使 用 Date 类 得 到 当 前 的 时 间 public Date(long date) 分 配 Date 对 象 并 初 始 化 此 对 象, 以 表 示 自 从 标 准 基 准 时 间 ( 称 为 历 元 (epoch), 即 1970 年 1 月 1 日 00:00:00 格 林 威 治 时 间 ) 以 来 的 指 定 毫 秒 数 常 用 方 法 public boolean after(date when) 测 试 此 日 期 是 否 在 指 定 日 期 之 后 public boolean before(date when) 测 试 此 日 期 是 否 在 指 定 日 期 之 前 方 法 :gettime() 返 回 自 1970 年 1 月 1 日 00:00:00 GMT 以 来 此 Date 对 象 表 示 的 毫 秒 数 示 例 简 单 的 性 能 测 试 监 控 一 段 代 码 运 行 所 需 要 的 时 间 public class Test { public static void main(string args[]) { long d1 = new Date().getTime();// 得 到 此 时 的 时 间 int sum = 0; for (int i = 1; i <= ; i++) {// 一 百 万 次 sum += i; System.out.println(" 从 1 加 到 的 和 =" + sum); long d2 = new Date().getTime();// 得 到 此 时 的 时 间 System.out.println(" 从 1 加 到 所 耗 费 的 时 间 是 =" + (d2 - d1) + " 毫 秒 "); 第 162 页

163 运 行 结 果 : 从 1 加 到 的 和 = 从 1 加 到 所 耗 费 的 时 间 是 =20 毫 秒 DateFormat 类 和 SimpleDateFormat 类 Date 对 象 表 示 时 间 的 默 认 顺 序 是 星 期 月 日 小 时 秒 年, 例 如 Wed May 12 14:33:11 CST 2009 我 们 可 能 希 望 按 照 某 种 习 惯 来 输 出 时 间, 比 如 时 间 的 顺 序 : 年 月 星 期 日 可 以 使 用 java.text 包 中 的 DateFormat 类, 是 日 期 / 时 间 格 式 化 子 类 的 抽 象 类, 它 以 与 语 言 无 关 的 方 式 格 式 化 并 解 析 日 期 或 时 间 日 期 / 时 间 格 式 化 子 类 ( 如 SimpleDateFormat) 允 许 进 行 格 式 化 ( 也 就 是 日 期 转 换 成 文 本 ) 解 析 ( 文 本 转 换 成 日 期 ) 和 标 准 化 由 于 DateFormat 是 个 抽 象 类,SimpleDateFormat 类 是 它 的 子 类, 所 以 下 面 就 主 要 按 照 SimpleDateFormat 类 来 讲 解 如 何 初 始 化 这 里 只 讲 述 最 常 用 到 的 构 造 方 法, 更 多 的 请 参 看 JDK 文 档 构 造 方 法 :SimpleDateFormat(String pattern) 用 给 定 的 模 式 和 默 认 语 言 环 境 的 日 期 格 式 符 号 构 造 SimpleDateFormat SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); 日 期 和 时 间 模 式 日 期 和 时 间 格 式 由 日 期 和 时 间 模 式 字 符 串 指 定 在 日 期 和 时 间 模 式 字 符 串 中, 未 加 引 号 的 字 母 'A' 到 'Z' 和 'a' 到 'z' 被 解 释 为 模 式 字 母, 用 来 表 示 日 期 或 时 间 字 符 串 元 素 文 本 可 以 使 用 单 引 号 (') 引 起 来, 以 免 进 行 解 释 "''" 表 示 单 引 号 所 有 其 他 字 符 均 不 解 释 ; 只 是 在 格 式 化 时 将 它 们 简 单 复 制 到 输 出 字 符 串, 或 者 在 解 析 时 与 输 入 字 符 串 进 行 匹 配 定 义 了 以 下 模 式 字 母 ( 所 有 其 他 字 符 'A' 到 'Z' 和 'a' 到 'z' 都 被 保 留 ): 字 母 日 期 或 时 间 元 素 表 示 示 例 G Era 标 志 符 Text AD y 年 Year 1996; 96 M 年 中 的 月 份 Month July; Jul; 07 w 年 中 的 周 数 Number 27 W 月 份 中 的 周 数 Number 2 D 年 中 的 天 数 Number 189 d 月 份 中 的 天 数 Number 10 F 月 份 中 的 星 期 Number 2 第 163 页

164 E 星 期 中 的 天 数 Text Tuesday; Tue a Am/pm 标 记 Text PM H 一 天 中 的 小 时 数 (0-23) Number 0 k 一 天 中 的 小 时 数 (1-24) Number 24 K am/pm 中 的 小 时 数 (0-11) Number 0 h am/pm 中 的 小 时 数 (1-12) Number 12 m 小 时 中 的 分 钟 数 Number 30 s 分 钟 中 的 秒 数 Number 55 S 毫 秒 数 Number 978 z 时 区 General time zone PST; GMT-08:00 Z 时 区 RFC 822 time zone 常 用 方 法 public Date parse(string source) 从 给 定 字 符 串 的 开 始 解 析 文 本, 以 生 成 一 个 日 期 public String format(date date) 将 一 个 Date 格 式 化 为 日 期 / 时 间 字 符 串 这 里 只 讲 述 最 常 用 的 方 法, 更 多 的 方 法 请 参 看 JDK 文 档 示 例 import java.util.*; import java.text.*; public class Test { public static void main(string args[]) { DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS"); Date d = new Date(); // 把 当 前 时 间 转 换 成 为 我 们 熟 悉 的 时 间 表 达 格 式 String str = df.format(d); System.out.println(" 当 前 时 间 是 :" + str); // 然 后 再 把 字 符 串 格 式 的 日 期 转 换 成 为 一 个 Date 类 try { Date d2 = df.parse(" :08:08 888"); System.out.println(" 伦 敦 奥 运 会 开 幕 时 间 是 :" + d2.gettime()); catch (ParseException e) { e.printstacktrace(); 运 行 结 果 : 当 前 时 间 是 : :52: 伦 敦 奥 运 会 开 幕 时 间 是 : 也 可 以 采 用 System 类 的 静 态 方 法 public long currenttimemillis() 获 取 系 统 当 前 第 164 页

165 时 间 的 毫 秒 数 说 明 虽 然 JDK 文 档 上 说 Date 的 毫 秒 值, 是 相 对 于 格 林 威 治 时 间 1970 年 1 月 1 号 的 0 点, 但 实 际 测 试, 这 个 Date 是 跟 时 区 相 关 的, 也 就 是 说 在 中 国 测 试 这 个 基 准 值 应 该 是 1970 年 1 月 1 日 的 8 点, 不 过 这 个 不 影 响 我 们 的 处 理, 因 为 只 要 是 同 一 个 基 准 时 间 就 可 以 了, 而 不 用 关 心 具 体 是 多 少, 见 下 面 的 示 例 : public class Test { public static void main(string args[]) { DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS"); Date d = new Date(0L);// 把 时 间 设 为 0, 表 示 到 基 准 时 间 // 然 后 转 换 成 为 字 符 串 看 看 是 什 么 时 候 String str = df.format(d); System.out.println(" 基 准 时 间 是 :" + str); 运 行 结 果 : 基 准 时 间 是 : :00: Calendar 类 java.util 包 中 的 Calendar 类 是 Java 里 面 另 外 一 个 常 用 的 日 期 处 理 的 类 Calendar 类 是 一 个 抽 象 类, 它 为 特 定 瞬 间 与 一 组 诸 如 YEAR MONTH DAY_OF_MONTH HOUR 等 日 历 字 段 之 间 的 转 换 提 供 了 一 些 方 法, 并 为 操 作 日 历 字 段 ( 例 如 获 得 下 星 期 的 日 期 ) 提 供 了 一 些 方 法 初 始 化 Calendar 类 是 通 过 一 个 静 态 方 法 getinstance() 来 获 取 Calendar 实 例 返 回 的 Calendar 基 于 当 前 时 间, 使 用 了 默 认 时 区 和 默 认 语 言 环 境 如 下 : Calendar c = Calendar.getInstance(); 使 用 Calendar 对 日 期 进 行 部 分 析 取 Calendar 类 一 个 重 要 的 功 能 就 是 能 够 从 日 期 里 面 按 照 要 求 析 取 出 数 据, 如 : 年 月 日 星 期 等 等 public int get(int field) 返 回 给 定 日 历 字 段 的 值, 例 如 年 份 月 份 小 时 星 期 等 信 息, 参 数 field 的 有 效 值 由 第 165 页

166 Calendar 得 静 态 常 量 指 定 示 例 如 下 : public class Test { public static void main(string args[]) { Calendar c = Calendar.getInstance(); int year = c.get(calendar.year); int month = c.get(calendar.month);// 注 意 :month 特 殊, 是 从 0 开 始 的, 也 就 是 0 表 示 1 月 int day = c.get(calendar.day_of_month); System.out.println(" 现 在 是 " + year + " 年 " + (month + 1) + " 月 " + day + " 日 "); 运 行 结 果 : 现 在 是 2009 年 5 月 17 日 使 用 Calendar 进 行 日 期 运 算 这 是 Calendar 另 外 一 个 常 用 的 功 能, 也 就 是 对 日 期 进 行 加 加 减 减 的 运 算 public void add(int field,int amount) 根 据 日 历 的 规 则, 为 给 定 的 日 历 字 段 添 加 或 减 去 指 定 的 时 间 量 示 例 如 下 : public class Test { public static void main(string args[]) { Calendar c = Calendar.getInstance(); c.add(calendar.date, 12);// 当 前 日 期 加 12 天, 如 果 是 -12 表 示 当 前 日 期 减 去 12 天 int year = c.get(calendar.year); // 注 意 :month 特 殊, 是 从 0 开 始 的, 也 就 是 0 表 示 1 月 int month = c.get(calendar.month); int day = c.get(calendar.day_of_month); System.out.println(" 在 当 前 日 期 加 12 天 是 " + year + " 年 " + (month + 1) + " 月 " + day+ " 日 "); 运 行 结 果 : 在 当 前 日 期 加 12 天 是 2009 年 5 月 29 日 第 166 页

167 为 Calendar 设 置 初 始 值 public void settime(date date) 使 用 给 定 的 Date 设 置 此 Calendar 的 当 前 时 间 public void settimeinmillis(long millis) 用 给 定 的 long 值 设 置 此 Calendar 的 当 前 时 间 值 public class Test { public static void main(string args[]) { Calendar c = Calendar.getInstance(); c.settimeinmillis( l); int year = c.get(calendar.year); // 注 意 :month 特 殊, 是 从 0 开 始 的, 也 就 是 0 表 示 1 月 int month = c.get(calendar.month); int day = c.get(calendar.day_of_month); System.out.println(" 设 置 的 时 间 是 " + year + " 年 " + (month + 1) + " 月 " + day+ " 日 "); 运 行 结 果 : 设 置 的 时 间 是 2009 年 2 月 14 日 6.7 包 装 类 虽 然 Java 语 言 是 典 型 的 面 向 对 象 编 程 语 言, 但 其 中 的 8 种 基 本 数 据 类 型 并 不 支 持 面 向 对 象 的 编 程 机 制, 基 本 类 型 的 数 据 不 具 备 对 象 的 特 性 ---- 不 携 带 属 性 没 有 方 法 可 调 用 沿 用 它 们 只 是 为 了 迎 合 人 类 根 深 蒂 固 的 习 惯, 并 的 确 能 简 单 有 效 地 进 行 常 规 数 据 处 理 这 种 借 助 于 非 面 向 对 象 技 术 的 做 法 有 时 也 会 带 来 不 便, 比 如 引 用 类 型 数 据 均 继 承 了 Object 类 的 特 性, 要 转 换 为 String 类 型 ( 经 常 有 这 种 需 要 ) 时 只 要 简 单 调 用 Object 类 中 定 义 的 tostring() 即 可, 而 基 本 数 据 类 型 转 换 为 String 类 型 则 要 麻 烦 得 多 为 解 决 此 类 问 题, Java 语 言 引 入 了 封 装 类 的 概 念, 在 JDK 中 针 对 各 种 基 本 数 据 类 型 分 别 定 义 相 应 的 引 用 类 型, 并 称 之 为 包 装 类 (Wrapper Classes) 下 表 描 述 了 基 本 数 据 类 型 及 对 应 的 包 装 类 基 本 数 据 类 型 byte short int long char float double 对 应 的 包 装 类 Byte Short Integer Long Character Float Double 第 167 页

168 boolean Boolean 每 个 包 装 类 的 对 象 可 以 封 装 一 个 相 应 的 基 本 类 型 的 数 据, 并 提 供 了 其 它 一 些 有 用 的 功 能 包 装 类 对 象 一 经 创 建, 其 内 容 ( 所 封 装 的 基 本 类 型 数 据 值 ) 不 可 改 变 例, 包 装 类 用 法 程 序 :Wrapper.java public class Wrapper { public static void main(string args[]) { int i = 500; Integer t = new Integer(i); int j = t.intvalue(); // j = 500 String s = t.tostring(); // s = "500" System.out.println(t); Integer t1 = new Integer(500); System.out.println(t.equals(t1)); 例 : 程 序 运 行 结 果 为 : 500 true 包 装 类 一 个 常 用 的 功 能 就 是 把 字 符 串 类 型 的 数 据 造 型 成 为 对 应 的 基 本 数 据 类 型, 如 下 示 String str = "123"; int a = Integer.parseInt(str); 6.8 System 类 命 令 行 参 数 当 Java 程 序 启 动 时, 可 以 添 加 0 或 多 个 命 令 行 参 数 (Command-line Arguments) 不 管 使 用 双 引 号 与 否 都 作 为 字 符 串 自 动 保 存 到 main 函 数 的 参 数 中 参 数 之 间 用 空 格 分 隔 public class Test { public static void main(string args[]) { System.out.println(args.length); for (int i = 0; i < args.length; i++) { System.out.println(args[i]); 第 168 页

169 本 段 代 码 可 以 使 用 下 面 语 句 测 试 :java Test 这 里 是 Java 快 车 运 行 结 果 : 4 这 里 是 Java 快 车 控 制 台 输 入 输 出 许 多 应 用 程 序 要 与 用 户 进 行 文 本 I/O( 输 入 / 输 出 ) 交 互, 标 准 输 入 是 键 盘 ; 标 准 输 出 是 终 端 窗 口 Java SDK 支 持 控 制 台 I/O 使 用 三 个 java.lang.system 类 中 定 义 的 变 量 : System.out 是 一 个 PrintStream 对 象, 初 始 引 用 启 动 Java 的 终 端 窗 口 System.in 是 一 个 InputStream 对 象, 初 始 指 向 用 户 键 盘 System.err 是 一 个 PrintStream 对 象, 初 始 引 用 启 动 Java 的 终 端 窗 口 这 三 个 对 象 都 可 以 重 新 定 向 ( 如 文 件 ):System.setOut\setIn\setErr 往 标 准 输 出 写 东 西 使 用 PrintStream 对 象 的 println 或 print 方 法 print 方 法 输 出 参 数 ; 但 println 方 法 输 出 参 数 并 追 加 一 个 换 行 符 println 或 print 方 法 都 对 原 始 类 型 进 行 重 载, 同 时 还 重 载 了 char[] 和 Object, String 参 数 是 Object 时, 调 用 参 数 的 tostring 方 法 输 出 例 子 : public class Test { public static void main(string args[]) { char c[] = { 'a', 'b', 'c' ; System.out.println(c); 运 行 结 果 :abc 输 入 例 子 : public class Test { public static void main(string args[]) { String s = ""; InputStreamReader ir = new InputStreamReader(System.in); BufferedReader in = new BufferedReader(ir); System.out.println("Ctrl+z to exit"); 第 169 页

170 try { s = in.readline(); while (s!= null) { System.out.println("Read:" + s); s = in.readline(); in.close(); catch (IOException e) { e.printstacktrace(); 运 行 的 时 候 从 控 制 台 输 入 数 据, 然 后 回 车, 就 看 到 输 出 了 读 入 的 数 据 因 为 涉 及 到 后 面 要 学 习 的 I/O 的 知 识, 所 以 这 里 先 简 单 了 解 一 下 也 可 以 使 用 Scanner 类,Scanner 类 用 来 扫 描 控 制 台 的 输 入 数 据 控 制 台 会 一 直 等 待 输 入, 直 到 敲 回 车 键 结 束, 把 所 输 入 的 内 容 传 给 Scanner, 作 为 扫 描 对 象 如 果 要 获 取 输 入 的 内 容, 则 只 需 要 调 用 Scanner 的 nextline() 方 法 即 可, 或 者 next nextint nextdouble 方 法 等 import java.util.scanner; public class Test { public static void main(string[] args) { Scanner sc = new Scanner(System.in); while(true){ String s=sc.next(); System.out.println(s); 格 式 化 输 出 printf 从 JDK5.0 开 始,Java 里 面 提 供 了 C 风 格 的 格 式 化 输 出 方 法 printf, 比 如 输 出 一 个 加 法 算 式,JDK5.0 版 本 以 前 的 写 法 是 : public class Test { public static void main(string[] args) { int x = 5; int y = 7; int nsum = x + y; System.out.println(x + " + " + y + " = " + nsum); 运 行 结 果 :5 + 7 = 12 而 在 JDK5.0 以 后 版 本 中 可 以 写 为 : 第 170 页

171 public class Test { public static void main(string[] args) { int x = 5; int y = 7; int nsum = x + y; System.out.printf("%d + %d = %d\n", x, y, nsum); 以 上 两 种 写 法 的 输 出 结 构 是 一 样 的, 即 = 12 这 种 改 变 不 仅 仅 是 形 式 上 的,printf 还 可 以 提 供 更 为 灵 活 强 大 的 输 出 功 能, 比 如 限 定 按 照 两 位 整 数 的 形 式 输 出, 可 以 写 为 : public class Test { public static void main(string[] args) { int x = 5; int y = 7; int nsum = x + y; System.out.printf("%02d + %02d = %02d\n", x, y, nsum); 运 行 输 出 结 果 将 是 = 12 其 实 这 个 功 能 在 Java 里 面 并 没 有 什 么 大 用, 具 体 的 printf 格 式 化 字 符 串 格 式 请 参 见 JDK 文 档 中 的 具 体 说 明 第 171 页

172 6.9 学 习 目 标 1. 学 会 使 用 JDK API 文 档 2. 掌 握 Object 类 中 的 equals hashcode tostring 方 法 的 作 用, 以 及 相 互 的 关 系 3. 掌 握 如 何 重 写 Object 类 中 的 equals hashcode tostring 方 法 4. equals 方 法 和 == 的 功 能 和 区 别 5. 至 少 掌 握 String 类 的 4 中 构 造 方 法 6. 理 解 String 类 的 存 储 结 构 7. 熟 练 掌 握 String 类 中 的 方 法 能 说 出 大 部 分 方 法 的 方 法 名 称 完 成 的 功 能, 甚 至 参 数 列 表 返 回 值 类 型 8. 了 解 正 则 表 达 式 完 成 的 功 能 9. 在 Java 中 使 用 正 则 表 达 式 完 成 验 证 功 能 10. 描 述 正 则 表 达 式 中 有 哪 些 元 字 符 11. 如 何 在 正 则 表 达 式 中 表 示 重 复 12. 如 何 在 正 则 表 达 式 中 表 示 字 符 类 13. 为 什 么 要 用 StringBuffer?(String 有 什 么 缺 点 ) 14. 描 述 StringBuffer 的 容 量 和 长 度 15. StringBuffer 为 我 们 提 供 了 哪 些 String 没 有 的 方 法 16. StringBuffer 和 StringBuilder 的 区 别 17. 描 述 Math 类 中 常 用 的 方 法 18. 掌 握 课 上 画 的 关 于 日 期 的 图, 注 意 相 互 之 间 的 转 换 个 基 本 数 据 类 型 对 应 8 个 包 装 类, 说 出 两 者 的 不 同 之 处 20. 理 解 自 动 包 装 和 解 包 21. 掌 握 如 何 通 过 System.in 创 建 扫 描 仪 Scanner, 如 何 使 用 Scanner 第 172 页

173 6.10 练 习 1. 设 计 一 个 员 工 类 Employee, 具 有 员 工 编 号 姓 名 性 别 住 址 出 生 日 期 属 性, 覆 盖 Object 的 equals 和 tostring 方 法 在 测 试 类 中, 分 别 创 建 两 个 员 工 对 象, 比 较 是 否 相 等, 并 打 印 员 工 信 息 2. 将 字 符 串 , 张 三, 男, 上 海 浦 东 新 区 15 号, 中 的 信 息 抽 取 出 来, 封 装 到 第 一 题 中 创 建 的 员 工 对 象 中 3. 有 11 个 人 一 起 喝 啤 酒, 每 个 人 喝 3 瓶, 每 个 酒 箱 内 有 6 瓶 啤 酒, 问 要 买 几 箱 啤 酒?( 用 java 程 序 解 答 ) 4. 编 写 一 个 程 序, 输 入 字 符 串, 通 过 substring 方 法, 将 字 符 串 逆 序 输 出 5. 下 列 代 码 编 译 并 运 行 的 结 果 是 : public class Test { public static void main(string[] args) { double num = 7.4; int a = (int) Math.abs(num + 0.5); int b = (int) Math.ceil(num + 0.5); int c = (int) Math.floor(num + 0.5); int d = (int) Math.round(num + 0.5); int e = (int) Math.round(num - 0.5); int f = (int) Math.floor(num - 0.5); int g = (int) Math.ceil(num - 0.5); int h = (int) Math.abs(num - 0.5); System.out.println("a=" + a); System.out.println("b=" + b); System.out.println("c=" + c); System.out.println("d=" + d); System.out.println("e=" + e); System.out.println("f=" + f); System.out.println("g=" + g); System.out.println("h=" + h); 6. 在 控 制 台 输 入 字 符 串, 用 正 则 表 达 式 验 证 是 否 只 包 含 数 字 和 英 文 字 母 7. ( 按 不 同 格 式 打 印 日 期 ) 在 上 午 信 函 中, 日 期 可 以 几 种 不 同 的 格 式 打 印, 两 种 比 较 常 用 的 格 式 如 下 :09/21/2012 和 July 21,1013 编 写 一 个 程 序, 读 取 第 一 种 日 期 格 式 的 日 期, 并 以 第 二 种 日 期 格 式 返 回 8. 编 写 一 个 程 序, 用 随 机 数 生 成 语 句 该 程 序 应 用 4 个 String 类 型 的 数 组, 它 们 分 别 是 article,noun,verb,preposition 该 程 序 按 下 列 顺 序 从 4 个 数 组 中 随 机 选 取 一 个 元 素 生 成 一 个 语 句 :article,noun,verb,preposition,article,noun 当 选 取 每 个 单 词 时, 应 该 特 别 注 意 上 述 单 词 组 成 的 数 组 是 否 足 够 大 要 求 : 单 词 之 间 用 空 格 分 开, 输 出 最 后 的 语 句 时, 应 以 大 写 字 母 开 头, 以 圆 点 结 尾 每 次 点 击 回 车 生 成 下 第 173 页

174 一 条 语 句 语 句 填 充 如 下 :article 数 组 包 含 冠 词 :the,a,one,some,any noun 数 组 包 含 名 词 boy,girl,doy,town,cat verb 数 组 包 含 动 词 drove,jumped,ran,walked,skipped preposition 数 组 应 包 含 介 词 to,from,over,under,on 9. 计 算 当 前 时 间 距 明 年 春 节 还 有 多 少 天 多 少 小 时 多 少 分 钟 多 少 秒 10. 将 26 个 英 文 字 母 用 逗 号 分 隔, 组 成 字 符 串 打 印 出 来 考 虑 效 率 问 题, 使 用 StringBuffer 或 者 StringBuilder 11. 设 计 一 个 银 行 帐 户 类, 具 有 户 名, 帐 号, 密 码, 余 额 等 属 性, 在 控 制 台 模 拟 登 录 退 出 存 款 取 款 等 方 法, 并 对 此 类 进 行 测 试 12. 编 写 程 序, 测 试 计 算 1~50 的 阶 乘 的 和 所 耗 费 的 毫 秒 级 时 间 阶 乘 : 例 如 5 的 阶 乘 等 于 5*4*3*2*1 13. 找 出 1~1000 之 间 的 全 部 同 构 数 注 : 如 果 一 个 数 出 现 在 其 平 方 数 的 右 端, 则 称 此 数 为 同 构 数 如 :1 在 1*1=1 的 右 端, 5 在 5*5=25 的 右 端,25 在 25*25=625 的 右 端 等 等 第 174 页

175 7 抽 象 类 和 接 口 7.1 抽 象 类 什 么 是 抽 象 类 有 时 在 开 发 中, 要 创 建 一 个 体 现 某 些 基 本 行 为 的 类, 并 为 该 类 声 明 方 法, 但 不 能 在 该 类 中 实 现 该 行 为, 而 是 在 子 类 中 实 现 该 方 法 这 种 只 给 出 方 法 定 义 而 不 具 体 实 现 的 方 法 被 称 为 抽 象 方 法, 抽 象 方 法 是 没 有 方 法 体 的, 在 代 码 的 表 达 上 就 是 没 有 { 怎 么 表 示 一 个 方 法 是 抽 象 的 呢? 使 用 abstract 修 饰 符 来 表 达 抽 象 abstract 修 饰 符 可 以 与 类 和 方 法 一 起 使 用 被 修 饰 的 类 不 能 被 实 例 化, 被 修 饰 的 方 法 必 须 在 包 含 此 方 法 的 类 的 子 类 中 被 实 现 抽 象 类 简 单 地 说 : 使 用 abstract 修 饰 的 类 就 是 抽 象 类 示 例 如 下 : public abstract class Test {// 抽 象 类 定 义 public abstract void doitbyhand();// 抽 象 方 法 定 义 抽 象 类 的 使 用 例 如, 考 虑 一 个 Drawing 类 该 类 包 含 用 于 各 种 绘 图 设 备 的 方 法, 但 这 些 必 须 以 独 立 平 台 的 方 法 实 现 它 不 可 能 去 访 问 机 器 的 录 像 硬 件 而 且 还 必 须 是 独 立 于 平 台 的 其 意 图 是 绘 图 类 定 义 哪 种 方 法 应 该 存 在, 但 实 际 上, 由 特 殊 的 从 属 于 平 台 子 类 去 实 现 这 个 行 为 正 如 Drawing 类 这 样 的 类, 它 声 明 方 法 的 存 在 而 不 是 实 现, 以 及 带 有 对 已 知 行 为 的 方 法 的 实 现, 这 样 的 类 通 常 被 称 做 抽 象 类 通 过 用 关 键 字 abstract 进 行 标 记 声 明 一 个 抽 象 类 被 声 明 但 没 有 实 现 的 方 法 ( 即, 这 些 没 有 程 序 体 或 {), 也 必 须 标 记 为 抽 象 public abstract class Drawing { public abstract void drawdot(int x, int y); public void drawline(int x1, int y1, int x2, int y2) { // draw using the drawdot() method repeatedly. 抽 象 类 不 能 直 接 使 用, 必 须 用 子 类 去 实 现 抽 象 类, 然 后 使 用 其 子 类 的 实 例 然 而 可 以 创 建 一 个 变 量, 其 类 型 是 一 个 抽 象 类, 并 让 它 指 向 具 体 子 类 的 一 个 实 例, 也 就 是 可 以 使 用 抽 象 类 来 充 当 形 参, 实 际 实 现 类 作 为 实 参, 也 就 是 多 态 的 应 用 第 175 页

176 不 能 有 抽 象 构 造 方 法 或 抽 象 静 态 方 法 abstract 类 的 子 类 为 它 们 父 类 中 的 所 有 抽 象 方 法 提 供 实 现, 否 则 它 们 也 是 抽 象 类 public class MachineDrawing extends Drawing { public void drawdot(int machx, int machy) { // 画 点 Drawing d = new MachineDrawing(); 在 下 列 情 况 下, 一 个 类 将 成 为 抽 象 类 : (1) 当 一 个 类 的 一 个 或 多 个 方 法 是 抽 象 方 法 时 ; (2) 当 类 是 一 个 抽 象 类 的 子 类, 并 且 不 能 为 任 何 抽 象 方 法 提 供 任 何 实 现 细 节 或 方 法 主 体 时 ; (3) 当 一 个 类 实 现 一 个 接 口, 并 且 不 能 为 任 何 抽 象 方 法 提 供 实 现 细 节 或 方 法 主 体 时 ; 注 意 : (1) 这 里 说 的 是 这 些 情 况 下 一 个 类 将 成 为 抽 象 类, 没 有 说 抽 象 类 一 定 会 有 这 些 情 况 (2) 一 个 典 型 的 错 误 : 抽 象 类 一 定 包 含 抽 象 方 法 但 是 反 过 来 说 包 含 抽 象 方 法 的 类 一 定 是 抽 象 类 就 是 正 确 的 (3) 事 实 上, 抽 象 类 可 以 是 一 个 完 全 正 常 实 现 的 类 7.2 接 口 的 基 本 概 念 接 口 可 以 说 是 Java 程 序 设 计 中 最 重 要 的 概 念 之 一 了, 面 向 接 口 编 程 是 面 向 对 象 世 界 的 共 识, 所 以 深 刻 理 解 并 熟 练 应 用 接 口 是 每 一 个 学 习 Java 编 程 人 员 的 重 要 任 务 接 口 概 念 Java 可 以 创 建 一 种 称 作 接 口 (interface) 的 类, 在 这 个 类 中, 所 有 的 成 员 方 法 都 是 抽 象 的, 也 就 是 说 它 们 都 只 有 定 义 而 没 有 具 体 实 现, 接 口 是 抽 象 方 法 和 常 量 值 的 定 义 的 集 合 从 本 质 上 讲, 接 口 是 一 种 特 殊 的 抽 象 类, 用 interface, 可 以 指 定 一 个 类 必 须 做 什 么, 而 不 是 规 定 它 如 何 去 做 定 义 接 口 的 语 法 格 式 如 下 : 访 问 修 饰 符 interface 接 口 名 称 { 抽 象 属 性 集 抽 象 方 法 集 现 实 中 也 有 很 多 接 口 的 实 例, 比 如 说 串 口 电 脑 硬 盘,Serial ATA 委 员 会 指 定 了 Serial ATA 2.0 规 范, 这 种 规 范 就 是 接 口 Serial ATA 委 员 会 不 负 责 生 产 硬 盘, 只 是 指 定 通 用 的 规 范 希 捷 日 立 三 星 等 生 产 厂 家 会 按 照 规 范 生 产 符 合 接 口 的 硬 盘, 这 些 硬 盘 就 可 以 实 第 176 页

177 现 通 用 化, 如 果 正 在 用 一 块 160G 日 立 的 串 口 硬 盘, 现 在 要 升 级 了, 可 以 购 买 一 块 320G 的 希 捷 串 口 硬 盘, 安 装 上 去 就 可 以 继 续 使 用 了 在 Java 中 可 以 模 拟 Serial ATA 委 员 会 定 义 以 下 串 口 硬 盘 接 口 // 串 行 硬 盘 接 口 public interface SataHdd{ // 连 接 线 的 数 量 public static final int CONNECT_LINE=4; // 写 数 据 public void writedata(string data); // 读 数 据 public String readdata(); 目 前 看 来 接 口 和 抽 象 类 差 不 多 确 实 如 此, 接 口 本 就 是 从 抽 象 类 中 演 化 而 来 的, 因 而 除 特 别 规 定, 接 口 享 有 和 类 同 样 的 待 遇 比 如, 源 程 序 中 可 以 定 义 多 个 类 或 接 口, 但 最 多 只 能 有 一 个 public 的 类 或 接 口, 如 果 有 则 源 文 件 必 须 取 和 public 的 类 和 接 口 相 同 的 名 字 和 类 的 继 承 格 式 一 样, 接 口 之 间 也 可 以 继 承, 子 接 口 可 以 继 承 父 接 口 中 的 常 量 和 抽 象 方 法 并 添 加 新 的 抽 象 方 法 等 但 接 口 有 其 自 身 的 一 些 特 性, 归 纳 如 下 : 接 口 中 声 明 的 成 员 变 量 默 认 都 是 public static final 的, 必 须 显 示 的 初 始 化 因 而 在 常 量 声 明 时 可 以 省 略 这 些 修 饰 符 接 口 中 只 能 定 义 抽 象 方 法, 这 些 方 法 默 认 为 public abstract 的, 因 而 在 声 明 方 法 时 可 以 省 略 这 些 修 饰 符 试 图 在 接 口 中 定 义 实 例 变 量 非 抽 象 的 实 例 方 法 及 静 态 方 法, 都 是 非 法 的 public interface SataHdd{ // 连 接 线 的 数 量 public int connectline;// 编 译 出 错,connectLine 是 静 态 常 量, 必 须 显 式 初 始 化 // 写 数 据 protected void writedata(string data); // 编 译 出 错, 必 须 是 public 类 型 // 读 数 据 public static String readdata(){ // 编 译 出 错, 接 口 中 不 能 包 含 静 态 方 法 return " 数 据 "; // 编 译 出 错, 接 口 中 只 能 包 含 抽 象 方 法, 接 口 中 没 有 构 造 方 法, 不 能 被 实 例 化 继 承 一 个 接 口 不 实 现 另 一 个 接 口, 但 可 以 继 承 多 个 其 他 接 口 接 口 的 多 继 承 特 点 弥 补 了 类 的 单 // 串 行 硬 盘 接 口 public interface SataHdd extends A,B{ // 连 接 线 的 数 量 第 177 页

178 public static final int CONNECT_LINE = 4; // 写 数 据 public void writedata(string data); // 读 数 据 public String readdata(); interface A{ public void a(); interface B{ public void b(); 为 什 么 使 用 接 口 两 个 类 中 的 两 个 类 似 的 功 能, 调 用 它 们 的 类 动 态 地 决 定 一 种 实 现, 那 它 们 提 供 一 个 抽 象 父 类, 子 类 分 别 实 现 父 类 所 定 义 的 方 法 问 题 的 出 现 :Java 是 一 种 单 继 承 的 语 言, 一 般 情 况 下, 哪 个 具 体 类 可 能 已 经 有 了 一 个 父 类, 解 决 是 给 它 的 父 类 加 父 类, 或 者 给 它 父 类 的 父 类 加 父 类, 只 到 移 动 到 类 等 级 结 构 的 最 顶 端 这 样 一 来, 对 一 个 具 体 类 的 可 插 入 性 的 设 计, 就 变 成 了 对 整 个 等 级 结 构 中 所 有 类 的 修 改 接 口 是 可 插 入 性 的 保 证 在 一 个 等 级 结 构 中 的 任 何 一 个 类 都 可 以 实 现 一 个 接 口, 这 个 接 口 会 影 响 到 此 类 的 所 有 子 类, 但 不 会 影 响 到 此 类 的 任 何 父 类 此 类 将 不 得 不 实 现 这 个 接 口 所 规 定 的 方 法, 而 其 子 类 可 以 从 此 类 自 动 继 承 这 些 方 法, 当 然 也 可 以 选 择 置 换 掉 所 有 的 这 些 方 法, 或 者 其 中 的 某 一 些 方 法, 这 时 候, 这 些 子 类 具 有 了 可 插 入 性 ( 并 且 可 以 用 这 个 接 口 类 型 装 载, 传 递 实 现 了 他 的 所 有 子 类 ) 我 们 关 心 的 不 是 哪 一 个 具 体 的 类, 而 是 这 个 类 是 否 实 现 了 我 们 需 要 的 接 口 接 口 提 供 了 关 联 以 及 方 法 调 用 上 的 可 插 入 性, 软 件 系 统 的 规 模 越 大, 生 命 周 期 越 长, 接 口 使 得 软 件 系 统 的 灵 活 性 和 可 扩 展 性, 可 插 入 性 方 面 得 到 保 证 接 口 把 方 法 的 特 征 和 方 法 的 实 现 分 割 开 来 这 种 分 割 体 现 在 接 口 常 常 代 表 一 个 角 色, 它 包 装 与 该 角 色 相 关 的 操 作 和 属 性, 而 实 现 这 个 接 口 的 类 便 是 扮 演 这 个 角 色 的 演 员 一 个 角 色 由 不 同 的 演 员 来 演, 而 不 同 的 演 员 之 间 除 了 扮 演 一 个 共 同 的 角 色 之 外, 并 不 要 求 其 它 的 共 同 之 处 对 于 下 述 情 况, 接 口 是 有 用 的 : (1) 声 明 方 法, 期 望 一 个 或 更 多 的 类 来 实 现 该 方 法 (2) 揭 示 一 个 对 象 的 编 程 接 口, 而 不 揭 示 类 的 实 际 程 序 体 ( 当 将 类 的 一 个 包 输 送 到 其 它 开 发 程 序 中 时 它 是 非 常 有 用 的 ) (3) 捕 获 无 关 类 之 间 的 相 似 性, 而 不 强 迫 类 关 系 第 178 页

179 (4) 可 以 作 为 参 数 被 传 递 到 在 其 它 对 象 上 调 用 的 方 法 中 面 向 对 象 程 序 设 计 讲 究 提 高 内 聚, 降 低 耦 合, 那 么 不 同 的 程 序 模 块 怎 么 相 互 访 问 呢, 就 是 通 过 接 口, 也 就 是 接 口 是 各 部 分 对 外 的 统 一 外 观 接 口 在 Java 程 序 设 计 中 体 现 的 思 想 就 是 隔 离, 因 为 接 口 只 是 描 述 一 个 统 一 的 行 为, 所 以 开 发 人 员 在 面 向 接 口 编 程 时 并 不 关 心 具 体 的 实 现 由 以 上 讲 到 的 接 口 的 作 用 和 基 本 思 想 可 以 看 到, 接 口 在 面 向 对 象 的 Java 程 序 设 计 中 占 有 举 足 轻 重 的 地 位 事 实 上 在 设 计 阶 段 最 重 要 的 任 务 之 一 就 是 设 计 出 各 部 分 的 接 口, 然 后 通 过 接 口 的 组 合, 形 成 程 序 的 基 本 框 架 结 构 7.3 接 口 作 为 类 型 使 用 接 口 的 使 用 接 口 的 使 用 与 类 的 使 用 有 些 不 同 在 需 要 使 用 类 的 地 方, 会 直 接 使 用 new 关 键 字 来 构 建 一 个 类 的 实 例 进 行 应 用 : ClassA a =new ClassA(); 这 是 正 确 的 但 接 口 不 可 以 这 样 用, 因 为 接 口 不 能 直 接 使 用 new 关 键 字 来 构 建 实 例 SataHdd sh = new SataHdd(); 这 是 错 误 的, 接 口 在 使 用 的 时 候 要 实 例 化 相 应 的 实 现 类 实 现 类 的 格 式 如 下 : 访 问 修 饰 符 修 饰 符 class 类 名 extends 父 类 implements 多 个 接 口 { 实 现 方 法 说 明 : 接 口 必 须 通 过 类 来 实 现 它 的 抽 象 方 法, 类 实 现 接 口 的 关 键 字 为 implements 如 果 一 个 类 不 能 实 现 该 接 口 的 所 有 抽 象 方 法, 那 么 这 个 类 必 须 被 定 义 为 抽 象 方 法 例 不 允 许 创 建 接 口 的 实 例, 但 允 许 定 义 接 口 类 型 的 引 用 变 量, 该 变 量 指 向 了 实 现 接 口 的 类 的 实 一 个 类 只 能 继 承 一 个 父 类, 但 却 可 以 实 现 多 个 接 口 // 希 捷 硬 盘 public class SeagateHdd implements SataHdd,A{ public String readdata() { // 希 捷 硬 盘 读 取 数 据 第 179 页

180 return " 数 据 "; public void writedata(string data) { // 希 捷 硬 盘 写 入 数 据 // 三 星 硬 盘 public class SamsungHdd implements SataHdd{ public String readdata() { // 三 星 硬 盘 读 取 数 据 return " 数 据 "; public void writedata(string data) { // 三 星 硬 盘 写 入 数 据 // 某 劣 质 硬 盘, 不 能 写 数 据 public abstract class XXHdd implements SataHdd{ public String readdata() { // 硬 盘 读 取 数 据 return " 数 据 "; public class Client{ public static void main(string[] args) { SataHdd sh1=new SeagateHdd(); // 初 始 化 希 捷 硬 盘 SataHdd sh2=new SamsungHdd(); // 初 始 化 三 星 硬 盘 接 口 作 为 类 型 使 用 接 口 作 为 引 用 类 型 来 使 用, 任 何 实 现 该 接 口 的 类 的 实 例 都 可 以 存 储 在 该 接 口 类 型 的 变 量 中, 通 过 这 些 变 量 可 以 访 问 类 中 所 实 现 的 接 口 中 的 方 法,Java 运 行 时 系 统 会 动 态 地 确 定 应 该 使 用 哪 个 类 中 的 方 法, 实 际 上 是 调 用 相 应 的 实 现 类 的 方 法 示 例 如 下 : public class Test { public void test1(a a) { a.dosth(); public static void main(string[] args) { Test t = new Test(); A a = new B(); t.test1(a); 第 180 页

181 public interface A { public int dosth(); public class B implements A { public int dosth() { System.out.println("now in B"); return 123; 运 行 结 果 :now in B 大 家 看 到 接 口 可 以 作 为 一 个 类 型 来 使 用, 把 接 口 作 为 方 法 的 参 数 和 返 回 类 型 7.4 接 口 和 抽 象 类 的 选 择 由 于 从 某 种 角 度 讲, 接 口 是 一 种 特 殊 的 抽 象 类, 它 们 的 渊 源 颇 深, 有 很 大 的 相 似 之 处, 所 以 在 选 择 使 用 谁 的 问 题 上 很 容 易 迷 糊 我 们 首 先 分 析 它 们 具 有 的 相 同 点 都 代 表 类 树 形 结 构 的 抽 象 层 在 使 用 引 用 变 量 时, 尽 量 使 用 类 结 构 的 抽 象 层, 使 方 法 的 定 义 和 实 现 分 离, 这 样 做 对 于 代 码 有 松 散 耦 合 的 好 处 都 不 能 被 实 例 化 都 能 包 含 抽 象 方 法 抽 象 方 法 用 来 描 述 系 统 提 供 哪 些 功 能, 而 不 必 关 心 具 体 的 实 现 抽 象 类 和 接 口 的 主 要 区 别 : 抽 象 类 可 以 为 部 分 方 法 提 供 实 现, 避 免 了 在 子 类 中 重 复 实 现 这 些 方 法, 提 高 了 代 码 的 可 重 用 性, 这 是 抽 象 类 的 优 势 ; 而 接 口 中 只 能 包 含 抽 象 方 法, 不 能 包 含 任 何 实 现 public abstract class A{ public abstract void method1(); public void method2(){ //A method2 public class B extends A{ public void method1(){ //B method1 public class C extends A{ public void method1(){ //C method1 第 181 页

182 抽 象 类 A 有 两 个 子 类 B C, 由 于 A 中 有 方 法 method2 的 实 现, 子 类 B C 中 不 需 要 重 写 method2 方 法, 我 们 就 说 A 为 子 类 提 供 了 公 共 的 功 能, 或 A 约 束 了 子 类 的 行 为 method2 就 是 代 码 可 重 用 的 例 子 A 并 没 有 定 义 method1 的 实 现, 也 就 是 说 B C 可 以 根 据 自 己 的 特 点 实 现 method1 方 法, 这 又 体 现 了 松 散 耦 合 的 特 性 再 换 成 接 口 看 看 : public interface A{ public void method1(); public void method2(); public class B implements A{ public void method1(){ //B method1 public void method2(){ //B method2 public class C implements A{ public void method1(){ //C method1 public void method2(){ //C method2 接 口 A 无 法 为 实 现 类 B C 提 供 公 共 的 功 能, 也 就 是 说 A 无 法 约 束 B C 的 行 为 B C 可 以 自 由 地 发 挥 自 己 的 特 点 现 实 method1 和 method2 方 法, 接 口 A 毫 无 掌 控 能 力 一 个 类 只 能 继 承 一 个 直 接 的 父 类 ( 可 能 是 抽 象 类 ), 但 一 个 类 可 以 实 现 多 个 接 口, 这 个 就 是 接 口 的 优 势 interface A{ public void method2(); interface B{ public void method1(); class C implements A,B{ public void method1(){ //C method1 public void method2(){ //C method2 // 可 以 如 此 灵 活 的 使 用 C, 并 且 C 还 有 机 会 进 行 扩 展, 实 现 其 他 接 口 A a=new C(); 第 182 页

183 B b=new C(); abstract class A{ public abstract void method1(); abstract class B extends A{ public abstract void method2(); class C extends B{ public void method1(){ //C method1 public void method2() { //C method2 对 于 C 类, 将 没 有 机 会 继 承 其 他 父 类 了 综 上 所 述, 接 口 和 抽 象 类 各 有 优 缺 点, 在 接 口 和 抽 象 类 的 选 择 上, 必 须 遵 守 这 样 一 个 原 则 : 行 为 模 型 应 该 总 是 通 过 接 口 而 不 是 抽 象 类 定 义 所 以 通 常 是 : (1) 优 先 选 用 接 口, 尽 量 少 用 抽 象 类 选 择 抽 象 类 的 时 候 通 常 是 如 下 情 况 : (2) 需 要 定 义 子 类 的 行 为, 又 要 为 子 类 提 供 共 性 的 功 能 第 183 页

184 7.5 学 习 目 标 1. 什 么 是 抽 象 方 法? 什 么 是 抽 象 类? 2. 在 Java 中 如 何 表 示 抽 象 类 和 抽 象 方 法 3. 抽 象 方 法 和 抽 象 类 的 关 系? 4. 抽 象 类 中 是 否 有 属 性, 抽 象 类 中 是 否 有 构 造 方 法 5. 如 何 使 用 抽 象 类 6. 什 么 是 接 口? 接 口 的 定 义 规 则? 7. 接 口 的 作 用? 为 什 么 使 用 接 口? 8. 举 例 说 明 如 何 把 接 口 当 作 类 型 使 用 9. 如 何 选 择 接 口 和 抽 象 类? 为 什 么? 7.6 练 习 1. 定 义 一 个 接 口 交 通 工 具, 说 明 交 通 工 具 可 以 移 动 实 现 交 通 工 具 而 产 生 汽 车 飞 机 轮 船, 并 定 义 类 来 实 现 其 移 动 的 方 法 2. 定 义 一 个 类 来 使 用 上 面 的 接 口 第 184 页

185 8 异 常 8.1 异 常 的 定 义 异 常 基 础 知 识 在 Java 编 程 语 言 中, 异 常 是 指 当 程 序 出 错 时 创 建 的 一 种 特 殊 的 运 行 时 错 误 对 象 注 意 这 个 错 误 不 是 编 译 时 的 语 法 错 误 Java 创 建 异 常 对 象 后, 就 发 送 给 Java 程 序, 即 抛 出 异 常 (throwing an exception) 程 序 捕 捉 到 这 个 异 常 后, 可 以 编 写 相 应 的 异 常 处 理 代 码 进 行 处 理, 而 不 是 让 程 序 中 断 使 用 异 常 处 理 可 以 提 高 程 序 的 健 壮 性, 有 助 于 调 试 和 后 期 维 护 在 程 序 执 行 中, 任 何 中 断 正 常 程 序 流 程 的 异 常 条 件 就 是 错 误 或 异 常 例 如, 发 生 下 列 情 况 时, 会 出 现 异 常 : - 想 打 开 的 文 件 不 存 在 - 网 络 连 接 中 断 - 受 控 操 作 数 超 出 预 定 范 围 - 正 在 装 载 的 类 文 件 丢 失 在 Java 编 程 语 言 中, 错 误 类 定 义 被 认 为 是 不 能 恢 复 的 严 重 错 误 条 件 在 大 多 数 情 况 下, 当 遇 到 这 样 的 错 误 时, 建 议 让 程 序 中 断 Java 编 程 语 言 实 现 异 常 处 理 来 帮 助 建 立 弹 性 代 码 在 程 序 中 发 生 错 误 时, 发 现 错 误 的 方 法 能 抛 出 一 个 异 常 到 其 调 用 程 序, 发 出 已 经 发 生 问 题 的 信 号 然 后, 调 用 方 法 捕 获 抛 出 的 异 常, 在 可 能 时, 再 恢 复 回 来 这 个 方 案 给 程 序 员 一 个 写 处 理 程 序 的 选 择, 来 处 理 异 常 通 过 浏 览 API, 可 以 了 解 方 法 抛 出 的 是 什 么 样 的 异 常 异 常 实 例 在 学 习 在 程 序 中 处 理 异 常 之 前, 看 一 看 如 果 不 处 理 异 常, 会 有 什 么 情 况 发 生 下 面 的 小 程 序 包 括 一 个 故 意 导 致 被 零 除 错 误 的 表 达 式 class Exc0 { public static void main(string args[]) { int d = 0; int a = 42 / d; 第 185 页

186 当 Java 运 行 时 系 统 检 查 到 被 零 除 的 情 况, 它 构 造 一 个 新 的 异 常 对 象 然 后 引 发 该 异 常 这 导 致 Exc0 的 执 行 停 止, 因 为 一 旦 一 个 异 常 被 引 发, 它 必 须 被 一 个 异 常 处 理 程 序 捕 获 并 且 被 立 即 处 理 该 例 中, 没 有 提 供 任 何 异 常 处 理 程 序, 所 以 异 常 被 Java 运 行 时 系 统 的 默 认 处 理 程 序 捕 获 任 何 不 是 被 你 程 序 捕 获 的 异 常 最 终 都 会 被 该 默 认 处 理 程 序 处 理 默 认 处 理 程 序 显 示 一 个 描 述 异 常 的 字 符 串, 打 印 异 常 发 生 处 的 堆 栈 轨 迹 并 且 终 止 程 序 下 面 是 由 标 准 javajdk 运 行 时 解 释 器 执 行 该 程 序 所 产 生 的 输 出 : java.lang.arithmeticexception: / by zero at Exc0.main(Exc0.java:4) 类 名 Exc0, 方 法 名 main, 文 件 名 Exc0.java 和 行 数 4 被 包 括 在 一 个 堆 栈 使 用 轨 迹 中, 用 于 提 示 异 常 所 发 生 的 位 置, 显 示 导 致 错 误 产 生 的 方 法 调 用 序 列 引 发 的 异 常 类 型 是 Exception 的 一 个 名 为 ArithmeticException 的 子 类, 该 子 类 更 明 确 的 描 述 了 何 种 类 型 的 错 误 方 法 Java 提 供 多 个 内 置 的 与 可 能 产 生 的 不 同 种 类 运 行 时 错 误 相 匹 配 的 异 常 类 型 下 面 是 前 面 程 序 的 另 一 个 版 本, 它 介 绍 了 相 同 的 错 误, 但 是 错 误 是 在 main() 方 法 之 外 的 另 一 个 方 法 中 产 生 的 : class Exc1 { static void subroutine() { int d = 0; int a = 10 / d; public static void main(string args[]) { Exc1.subroutine(); 默 认 异 常 处 理 器 的 堆 栈 轨 迹 结 果 表 明 了 整 个 调 用 栈 是 怎 样 显 示 的 : java.lang.arithmeticexception: / by zero at Exc1.subroutine(Exc1.java:4) at Exc1.main(Exc1.java:7) 栈 底 是 main 的 第 7 行, 该 行 调 用 了 subroutine() 方 法 该 方 法 在 第 4 行 导 致 了 异 常 调 用 堆 栈 对 于 调 试 来 说 是 很 重 要 的, 因 为 它 查 明 了 导 致 错 误 的 精 确 的 步 骤 8.2 异 常 的 处 理 Java 提 供 了 一 种 异 常 处 理 模 型, 它 使 您 能 检 查 异 常 并 进 行 相 应 的 处 理 它 实 现 的 是 异 常 处 理 的 抓 抛 模 型 使 用 此 模 型, 您 只 需 要 注 意 有 必 要 加 以 处 理 的 异 常 情 况 Java 提 供 的 这 种 异 常 处 理 模 型, 代 替 了 用 返 回 值 或 参 数 机 制 从 方 法 返 回 异 常 码 的 手 段 异 常 处 理 的 抓 抛 方 法 有 两 大 优 点 : (1) 异 常 情 况 能 仅 在 有 必 要 之 处 加 以 处 理, 防 止 程 序 自 动 终 止, 而 不 在 其 发 生 处 和 需 要 进 行 处 理 处 之 间 的 每 一 级 上 均 进 行 处 理 第 186 页

187 (2) 能 够 编 写 统 一 的 可 重 用 的 异 常 处 理 代 码 应 该 区 别 对 待 程 序 中 的 正 常 控 制 流 和 异 常 处 理 流 当 然, 异 常 处 理 流 也 是 程 序 中 的 控 制 流 当 异 常 发 生 时, 抛 出 一 个 异 常 异 常 伴 随 调 用 链, 直 到 它 们 被 捕 获 或 程 序 退 出 为 止 下 面 是 Java 语 言 中 的 异 常 处 理 块 的 模 型 : try { // 放 置 可 能 出 现 异 常 的 代 码 catch (Exception1 el) { // 如 果 try 块 抛 出 异 常 对 象 的 类 型 为 Exceptionl, 那 么 就 在 这 里 进 行 处 理 catch (Exception2 e2) { // 如 果 try 块 抛 出 异 常 对 象 的 类 型 为 Exception2, 那 么 就 在 这 里 进 行 处 理 catch (ExceptionN en) { // 如 果 try 块 抛 出 异 常 对 象 的 类 型 为 ExceptionN, 那 么 就 在 这 里 进 行 处 理 finally { // 不 管 是 否 有 异 常 发 生, 始 终 执 行 这 个 代 码 块 在 未 提 供 适 当 异 常 处 理 机 制 的 程 序 中, 无 论 何 时 发 生 异 常, 程 序 均 会 异 常 中 断, 而 之 前 分 配 的 所 有 资 源 则 保 持 其 状 态 不 变 这 会 导 致 资 源 遗 漏 要 避 免 这 一 情 况, 在 适 当 的 异 常 处 理 机 制 中, 我 们 可 以 将 以 前 由 系 统 分 配 的 所 有 资 源 返 还 给 系 统 所 以, 当 异 常 可 能 发 生 时, 要 牢 记 必 须 对 每 一 异 常 分 别 进 行 处 理 例 如 我 们 处 理 文 件 I/O, 在 打 开 文 件 时 发 生 IOException, 程 序 异 常 中 断 而 没 有 机 会 关 闭 该 文 件, 这 可 能 会 毁 坏 文 件 而 且 分 配 给 该 文 件 的 操 作 系 统 资 源 可 能 未 返 还 给 系 统 try-catch try 块 由 一 组 可 执 行 语 句 组 成, 在 执 行 它 们 时 可 能 会 抛 出 异 常 catch 块, 是 用 来 捕 获 并 处 理 try 中 抛 出 的 异 常 的 代 码 块 catch 块 不 能 单 独 存 在, 可 以 有 多 个 catch 块, 以 捕 获 不 同 类 型 的 异 常 try 不 可 以 跟 随 在 catch 块 之 后 class Exc0 { public static void main(string args[]) { try { int d = 0; int a = 1 / d; System.out.println("This will not be printed"); catch (ArithmeticException e) { System.out.println("Division by zero"); System.out.println("After catch statement"); 第 187 页

188 程 序 将 会 发 生 异 常 而 中 断, 异 常 可 在 catch 块 中 被 捕 获, 输 出 如 下 : Division by zero After catch statement 在 try 块 中 对 println() 的 调 用 是 不 会 执 行 的 一 旦 异 常 被 引 发, 程 序 控 制 由 try 块 转 到 catch 块 执 行 永 远 不 会 从 catch 块 返 回 到 try 块 因 此, 第 6 行 将 不 会 被 执 行 一 旦 执 行 了 catch 语 句, 程 序 控 制 从 整 个 try/catch 机 制 的 下 面 一 行 ( 第 10 行 ) 继 续 一 个 try 和 它 的 catch 语 句 形 成 了 一 个 单 元 catch 子 句 的 范 围 限 制 于 try 语 句 前 面 所 定 义 的 语 句 一 个 catch 语 句 不 能 捕 获 另 一 个 try 声 明 所 引 发 的 异 常 ( 除 非 是 嵌 套 的 try 语 句 情 况 ) 被 try 保 护 的 语 句 声 明 必 须 在 一 个 大 括 号 之 内 ( 也 就 是 说, 它 们 必 须 在 一 个 块 中 ) 不 能 单 独 使 用 try 构 造 catch 子 句 的 目 的 是 解 决 异 常 情 况 并 且 像 错 误 没 有 发 生 一 样 继 续 运 行 例 如, 下 面 的 程 序 中, 每 一 个 for 循 环 的 反 复 得 到 两 个 随 机 整 数 这 两 个 整 数 分 别 被 对 方 除, 结 果 用 来 除 1000 最 后 的 结 果 存 在 a 中 如 果 一 个 除 法 操 作 导 致 被 零 除 错 误, 它 将 被 捕 获,a 的 值 设 为 零, 程 序 继 续 运 行 import java.util.random; class HandleError { public static void main(string args[]) { int a = 0, b = 0, c = 0; Random r = new Random(); for (int i = 0; i < 10; i++) { try { b = r.nextint(); c = r.nextint(); a = 1000 / (b / c); catch (ArithmeticException e) { System.out.println("Division by zero."); a = 0; // set a to zero and continue System.out.println("a: " + a); try 块 可 以 嵌 套, 也 就 是 说, 一 个 try 语 句 可 以 在 另 一 个 try 块 内 部 每 次 进 入 try 语 句, 异 常 的 前 后 关 系 都 会 被 推 入 堆 栈 如 果 一 个 内 部 的 try 语 句 不 含 特 殊 异 常 的 catch 处 理 程 序, 堆 栈 将 弹 出, 下 一 个 try 语 句 的 catch 处 理 程 序 将 检 查 是 否 与 之 匹 配 这 个 过 程 将 继 续 直 到 一 个 catch 语 句 匹 配 成 功, 或 者 是 直 到 所 有 的 嵌 套 try 语 句 被 检 查 耗 尽 如 果 没 有 catch 语 句 匹 配,Java 的 运 行 时 系 统 将 处 理 这 个 异 常 下 面 是 运 用 嵌 套 try 语 句 的 一 个 例 子 : class Exc0 { public static void main(string args[]) { try { int a = 1 / 0; try { 第 188 页

189 int b = 2 / 0; catch (Exception e2) { // 异 常 处 理 System.out.println("e2"); catch (Exception e) { // 异 常 处 理 System.out.println("e1"); 当 执 行 到 第 4 行 代 码 时, 发 生 了 异 常, 被 第 11 行 的 catch 捕 捉 到, 再 执 行 第 14 行 的 异 常 处 理 代 码, 而 不 执 行 第 5 行 至 第 10 行 的 代 码 如 果 第 4 行 没 有 异 常 产 生, 将 会 捕 捉 到 第 6 行 代 码 的 异 常 当 多 个 catch 块 存 在 的 时 候, 从 上 往 下 catch 异 常 的 范 围 应 该 从 小 到 大, 因 为 catch 块 的 运 行 机 制 是 找 到 一 个 匹 配 的 就 进 行 处 理 了, 如 果 把 范 围 大 的 放 在 前 面, 那 么 后 面 的 代 码 就 没 有 机 会 运 行 了, 这 会 是 一 个 编 译 异 常 比 如 下 面 这 个 是 正 确 的 : public class Exc0 { public static void main(string[] args) { try { int a = 5 / 0; catch (ArithmeticException e) { e.printstacktrace(); catch (Exception err) { err.printstacktrace(); 而 下 面 这 个 就 是 错 误 的 了, 编 译 都 发 生 了 错 误 : public class Exc0 { public static void main(string[] args) { try { int a = 1 / 0; catch (Exception err) { err.printstacktrace(); catch (ArithmeticException e) { e.printstacktrace(); 第 189 页

190 8.2.2 finally 块 finally 块 表 示 : 无 论 是 否 出 现 异 常, 都 会 运 行 的 块 通 常 在 finally 块 中 可 以 编 写 资 源 返 还 给 系 统 的 语 句, 通 常, 这 些 语 句 包 括 但 不 限 于 : (1) 释 放 动 态 分 配 的 内 存 块 : (2) 关 闭 文 件 ; (3) 关 闭 数 据 库 结 果 集 ; (4) 关 闭 与 数 据 库 建 立 的 连 接 ; 它 紧 跟 着 最 后 一 个 块, 是 可 选 的, 不 论 是 否 抛 出 异 常, finally 块 总 会 被 执 行 finally 块 的 语 法 如 下 : try{ catch( 异 常 类 型 1 e){ catch( 异 常 类 型 2 e){ finally{ 下 面 的 程 序 显 示 的 是 finally 块 的 使 用 public class Test { static String name; static int n01, n02; public static void main(string args[]) { try { name = "Aptech Limited"; n01 = Integer.parseInt(args[0]); n02 = Integer.parseInt(args[1]); System.out.println(name); System.out.println("Division is" + n01 / n02); catch (ArithmeticException i) { System.out.println("Can not be divided by zero!"); finally { name = null; System.out.println("finally executed"); 从 下 面 的 命 令 行 执 行 此 程 序 : Java Test 20 0 将 会 得 到 下 面 的 输 出 : 第 190 页

191 Aptech Limited Can not be divided by zero! finally executed 现 在 从 下 面 的 命 令 行 执 行 此 程 序 : Java Test 20 4 则 会 得 到 下 面 这 样 的 输 出 : Aptech Limited Division is 5 finally executed 说 明 : 当 用 不 同 的 命 令 行 参 数 执 行 此 程 序 时, 均 会 看 见 finally executed 的 输 出 这 意 味 着, 无 论 try 块 是 否 抛 出 异 常, 都 会 执 行 finally 块 思 考 题 : 是 否 会 执 行 第 7 行 代 码? try{ System.out.println(1); return ; catch(exception e){ e.printstacktrace(); finally{ System.out.println(11); try catch finally 块 的 关 系 (1)try 块 不 能 单 独 存 在, 后 面 必 须 跟 catch 块 或 者 finally 块 (2) 三 者 之 间 的 组 合 为 :try catch try catch finally try finally 这 几 种 是 合 法 的 (3) 一 个 try 块 可 以 有 多 个 catch 块, 从 上 到 下 多 个 catch 块 的 范 围 为 从 小 到 大 throw 语 句 throw 语 句 用 来 从 代 码 中 主 动 抛 出 异 常, 可 以 将 它 理 解 为 一 个 向 上 抛 出 的 动 作 throw 的 操 作 数 是 任 一 种 异 常 类 对 象 是 Throwable 类 类 型 或 Throwable 子 类 类 型 的 一 个 对 象 简 单 类 型, 例 如 int 或 char, 以 及 非 Throwable 类, 例 如 String 或 Object, 不 能 用 作 异 常 程 序 执 行 在 throw 语 句 之 后 立 即 停 止 ; 后 面 的 任 何 语 句 不 被 执 行 最 紧 紧 包 围 的 try 块 用 来 检 查 它 是 否 含 有 一 个 与 异 常 类 型 匹 配 的 catch 语 句 如 果 发 现 了 匹 配 的 块, 控 制 转 向 该 语 句 ; 如 果 没 有 发 现, 次 包 围 的 try 块 来 检 查, 以 此 类 推 如 果 没 有 发 现 匹 配 的 catch 块, 默 认 异 常 处 理 程 序 中 断 程 序 的 执 行 并 且 打 印 堆 栈 轨 迹 第 191 页

192 下 面 是 throw 关 键 字 的 一 个 示 例 : try { int i = 5/0; catch (ArithmeticException i) { throw new Exception("Can not be divided by zero!"); System.out.println("after throw"); 第 2 行 代 码 产 生 异 常, 然 后 执 行 catch 块 中 的 代 码, 第 4 行 抛 出 新 异 常, 将 不 再 执 行 第 5 行 代 码 序 下 面 是 一 个 创 建 并 引 发 异 常 的 例 子 程 序, 与 异 常 匹 配 的 处 理 程 序 再 把 它 引 发 给 外 层 的 处 理 程 class ThrowDemo { static void demoproc() { try { throw new NullPointerException("demo"); catch (NullPointerException e) { System.out.println("Caught inside demoproc."); throw e; // rethrow the exception public static void main(string args[]) { try { demoproc(); catch (NullPointerException e) { System.out.println("Recaught: " + e); 该 程 序 有 两 个 机 会 处 理 相 同 的 错 误 首 先, main() 设 立 了 一 个 异 常 关 系 然 后 调 用 demoproc() demoproc() 方 法 然 后 设 立 了 另 一 个 异 常 处 理 关 系 并 且 立 即 引 发 一 个 新 的 NullPointerException 实 例,NullPointerException 在 下 一 行 被 捕 获 异 常 于 是 被 再 次 引 发 下 面 是 输 出 结 果 : Caught inside demoproc. Recaught: java.lang.nullpointerexception: demo 该 程 序 还 阐 述 了 怎 样 创 建 Java 的 标 准 异 常 对 象, 特 别 注 意 下 面 这 一 行 : throw new NullPointerException("demo"); 这 里,new 用 来 构 造 一 个 NullPointerException 实 例 所 有 的 Java 内 置 的 运 行 时 异 常 有 两 个 构 造 函 数 : 一 个 没 有 参 数, 一 个 带 有 一 个 字 符 串 参 数 当 用 到 第 二 种 形 式 时, 参 数 指 定 描 述 异 常 的 字 符 串 如 果 对 象 用 作 print() 或 println() 的 参 数 时, 该 字 符 串 被 显 示 这 同 样 可 以 通 过 调 用 getmessage() 来 实 现,getMessage() 是 由 Throwable 定 义 的 第 192 页

193 8.2.5 throws 语 句 throws 用 来 在 方 法 定 义 时 声 明 异 常 Java 中 对 异 常 的 处 理 有 两 种 方 法, 一 个 就 是 try-catch, 然 后 自 己 处 理 ; 一 个 就 是 不 做 处 理, 向 外 throws, 由 调 用 该 方 法 的 代 码 去 处 理 Java 语 言 要 求 在 方 法 定 义 中 列 出 该 方 法 抛 出 的 异 常 : public class Example{ public static void exceptionexample() throws ExampleException,LookupException{ 在 上 面 的 示 例 中,exceptionExample() 声 明 包 括 throws 关 键 字, 其 后 列 出 了 此 方 法 可 能 抛 出 的 异 常 列 表 在 此 案 例 中 列 出 的 是 ExampleException 和 LookupException 比 如 前 面 那 个 例 子 写 完 整 如 下 : public class Exc0 { public static void main(string args[]) throws Exception { try { int a = 1 / 0; catch (ArithmeticException i) { throw new Exception("Can not be divided by zero!"); 调 用 栈 机 制 如 果 方 法 中 的 一 个 语 句 抛 出 一 个 没 有 在 相 应 的 try/catch 块 中 处 理 的 异 常, 那 么 这 个 异 常 就 被 抛 出 到 调 用 方 法 中 如 果 异 常 也 没 有 在 调 用 方 法 中 被 处 理, 它 就 被 抛 出 到 该 方 法 的 调 用 程 序 这 个 过 程 要 一 直 延 续 到 异 常 被 处 理 如 果 异 常 到 这 时 还 没 被 处 理, 它 便 回 到 main(), 而 且, 即 使 main() 不 处 理 它, 那 么, 该 异 常 就 异 常 地 中 断 程 序 考 虑 这 样 一 种 情 况, 在 该 情 况 中 main( ) 方 法 调 用 另 一 个 方 法 ( 比 如,first( )), 然 后 它 调 用 另 一 个 ( 比 如,second( )) 如 果 在 second( ) 中 发 生 异 常, 那 么 必 须 做 一 个 检 查 来 看 看 该 异 常 是 否 有 一 个 catch; 如 果 没 有, 那 么 对 调 用 栈 (first( )) 中 的 下 一 个 方 法 进 行 检 查, 然 后 检 查 下 一 个 (main()) 如 果 这 个 异 常 在 该 调 用 栈 上 没 有 被 最 后 一 个 方 法 处 理, 那 么 就 会 发 生 一 个 运 行 时 错 误, 程 序 终 止 执 行 第 193 页

194 8.3 异 常 的 分 类 异 常 的 分 类 在 Java 编 程 语 言 中, 异 常 有 两 种 分 类 java.lang.throwable 类 充 当 所 有 对 象 的 父 类, 可 以 使 用 异 常 处 理 机 制 将 这 些 对 象 抛 出 并 捕 获 在 Throwable 类 中 定 义 方 法 来 检 索 与 异 常 相 关 的 错 误 信 息, 并 打 印 显 示 异 常 发 生 的 栈 跟 踪 信 息 它 有 Error 和 Exception 两 个 基 本 子 类 错 误 (Error):JVM 系 统 内 部 错 误 资 源 耗 尽 等 严 重 情 况 ; 异 常 (Exception 违 例 ): 其 它 因 编 程 错 误 或 偶 然 的 外 在 因 素 导 致 的 一 般 性 问 题, 例 如 : 对 负 数 开 平 方 根 空 指 针 访 问 试 图 读 取 不 存 在 的 文 件 网 络 连 接 中 断 等 当 发 生 Error 时, 程 序 员 根 本 无 能 为 力, 只 能 让 程 序 终 止 比 如 说 内 存 溢 出, 不 可 能 指 望 程 序 能 处 理 这 样 的 情 况 而 对 于 Exception, 而 有 补 救 或 控 制 的 可 能, 程 序 员 也 可 以 预 先 防 范, 本 章 主 要 讨 论 Exception 的 处 理 为 有 效 地 描 述 异 常 状 况 传 递 有 关 的 异 常 信 息,JDK 中 针 对 各 种 普 遍 性 的 异 常 情 况 定 义 了 多 种 异 常 类 型 其 层 次 关 系 如 下 图 所 示 : VirtualMachineError LinkageError Error AWTError IOError Throwable ClassCastException RuntimeException ArrayIndexOutOfBound sexception EventException Exception SAXException FileNotFoundException IOException EOFException 第 194 页 FilterException

195 异 常 分 为 运 行 时 异 常 和 受 检 查 异 常 RuntimeException( 运 行 时 异 常 ) 是 指 因 设 计 或 实 现 方 式 不 当 导 致 的 问 题 也 可 以 说, 是 程 序 员 的 原 因 导 致 的, 本 来 可 以 避 免 发 生 的 情 况 比 如, 如 果 事 先 检 查 数 组 元 素 下 标 保 证 其 不 超 出 数 组 长 度, 那 么,ArrayIndexOutOfBoundsException 异 常 从 不 会 抛 出 ; 再 如, 先 检 查 并 确 保 一 个 引 用 类 型 变 量 值 不 为 null, 然 后 在 令 其 访 问 所 需 的 属 性 和 方 法, 那 么, NullPointerException 也 就 从 不 会 产 生 这 种 异 常 的 特 点 是 Java 编 译 器 不 会 检 查 它, 也 就 是 说 程 序, 程 序 中 可 能 出 现 这 类 异 常 时, 即 使 没 有 用 try-catch 语 句 捕 获 它, 也 没 有 用 throws 语 句 声 明 抛 出 它, 还 是 会 编 译 通 过 的 由 于 没 有 处 理 它, 当 出 现 这 类 异 常 时, 异 常 对 象 一 直 被 传 递 到 main() 方 法, 则 程 序 将 异 常 终 止 如 果 采 用 了 异 常 处 理, 异 常 将 会 被 相 应 的 程 序 执 行 处 理 除 了 RuntimeException 以 及 子 类, 其 他 的 Exception 及 其 子 类 都 是 受 检 查 异 常 这 种 异 常 的 特 点 是 Java 编 译 器 不 会 检 查 它, 也 就 是 说, 当 程 序 中 出 现 这 类 异 常 时, 要 么 用 try-catch 语 句 捕 获 它, 也 没 有 用 throws 语 句 声 明 抛 出 它, 否 则 编 译 不 会 通 过 这 些 异 常 的 产 生 不 是 因 为 程 序 员 的 过 错, 是 程 序 员 无 法 预 见 的 总 结 一 下,Java 程 序 异 常 处 理 的 原 则 为 : 的 ; (1) 对 于 Error 和 RuntimeException, 可 以 在 程 序 中 进 行 捕 获 和 处 理, 但 不 是 必 须 (2) 对 于 其 它 异 常, 必 须 在 程 序 中 进 行 捕 获 和 处 理 预 定 义 异 常 Java 编 程 语 言 中 预 先 定 义 好 的 异 常 叫 预 定 义 异 常, 上 面 提 到 的 异 常 都 是 预 定 义 异 常, 这 些 异 常 的 产 生 不 需 要 程 序 员 手 动 抛 出, 即 不 需 要 使 用 throw 语 句 抛 出 异 常, 当 产 生 异 常 时, 系 统 会 自 动 抛 出 下 面 是 几 种 常 见 的 异 常 : JDK 中 定 义 的 RuntimeException 子 类 名 称 描 述 ArithmeticException 算 术 错 误, 如 被 0 除 NullPointerException 非 法 使 用 空 引 用 ArrayIndexOutOfBoundsException 数 组 下 标 越 界 NegativeArraySizeException 创 建 带 负 维 数 大 小 的 数 组 的 尝 试 ClassCastException 非 法 强 制 转 换 类 型 ArrayStoreException 数 组 元 素 赋 值 类 型 不 兼 容 IllegalArgumentException 调 用 方 法 的 参 数 非 法 IllegalMonitorStateException 非 法 监 控 操 作, 如 等 待 一 个 未 锁 定 线 程 IllegalStateException 环 境 或 应 用 状 态 不 正 确 IllegalThreadStateException 请 求 操 作 与 当 前 线 程 状 态 不 兼 容 IndexOutOfBoundsException 某 些 类 型 索 引 越 界 NumberFormatException 字 符 串 到 数 字 格 式 非 法 转 换 第 195 页

196 SecurityException StringIndexOutOfBounds UnsupportedOperationException 试 图 违 反 安 全 性 试 图 在 字 符 串 边 界 之 外 索 引 遇 到 不 支 持 的 操 作 JDK 中 的 定 义 的 受 检 查 异 常 名 称 描 述 ClassNotFoundException 找 不 到 类 CloneNotSupportedException 试 图 克 隆 一 个 不 能 实 现 Cloneable 接 口 的 对 象 IllegalAccessException 对 一 个 类 的 访 问 被 拒 绝 InstantiationException 试 图 创 建 一 个 抽 象 类 或 者 抽 象 接 口 的 对 象 InterruptedException 一 个 线 程 被 另 一 个 线 程 中 断 NoSuchFieldException 请 求 的 字 段 不 存 在 NoSuchMethodException 请 求 的 方 法 不 存 在 自 定 义 异 常 Java 语 言 允 许 用 户 在 需 要 时 创 建 自 己 的 异 常 类 型, 用 于 表 述 JDK 中 未 涉 及 到 的 其 它 异 常 状 况, 这 些 类 型 也 必 须 继 承 Throwable 类 或 其 子 类 用 户 自 定 义 异 常 类 通 常 属 Exception 范 畴, 依 据 命 名 惯 例, 应 以 Exception 结 尾 用 户 自 定 义 异 常 未 被 加 入 JRE 的 控 制 逻 辑 中, 因 此 永 远 不 会 自 动 抛 出, 只 能 由 人 工 创 建 并 抛 出 Throwable 定 义 的 方 法 方 法 描 述 String getlocalizedmessage( ) 返 回 一 个 异 常 的 局 部 描 述 String getmessage( ) 返 回 一 个 异 常 的 描 述 void printstacktrace( ) 显 示 堆 栈 轨 迹 void printstacktrace(printstreamstream) 把 堆 栈 轨 迹 送 到 指 定 的 流 void printstacktrace(printwriterstream) 把 堆 栈 轨 迹 送 到 指 定 的 流 String tostring( ) 返 回 一 个 包 含 异 常 描 述 的 String 对 象 当 输 出 一 个 Throwable 对 象 时, 该 方 法 被 println( ) 调 用 看 一 个 用 户 自 定 义 异 常 的 例 子 : class MyException extends Exception { private int idnumber; public MyException(String message, int id) { super(message); this.idnumber = id; public int getid() { return idnumber; 第 196 页

197 public class Test { public void regist(int num) throws MyException { if (num < 0) { throw new MyException(" 人 数 为 负 值, 不 合 理 ", 3); System.out.println(" 登 记 人 数 " + num); public void manager() { try { regist(-100); catch (MyException e) { System.out.print(" 登 记 出 错, 类 别 :" + e.getid()); System.out.print(" 本 次 登 记 操 作 结 束 "); public static void main(string args[]) { Test t = new Test(); t.manager(); 第 197 页

198 8.4 学 习 目 标 1. 什 么 是 异 常? 2. 简 述 处 理 异 常 的 两 种 方 式? 3. 简 述 try 块 的 功 能 和 规 则 4. 简 述 catch 块 的 功 能 和 规 则 5. 简 述 finally 块 的 功 能 和 规 则 6. 简 述 throw 和 throws 的 功 能 和 使 用 方 法 7. 理 解 什 么 时 候 用 抓, 什 么 时 候 用 抛 8. 异 常 的 分 类? 9. 什 么 是 受 检 查 异 常, 描 述 其 特 点 10. 什 么 是 运 行 时 异 常, 描 述 其 特 点 11. 什 么 是 预 定 义 异 常 12. 简 述 自 定 义 异 常 的 规 则 第 198 页

199 9 集 合 框 架 9.1 基 本 概 念 数 学 背 景 在 常 见 用 法 中, 集 合 (Collection) 和 数 学 上 直 观 的 集 (set) 的 概 念 是 相 同 的 集 是 一 个 唯 一 项 组, 也 就 是 说 组 中 没 有 重 复 项 实 际 上, 集 合 框 架 包 含 了 一 个 Set 接 口 和 许 多 具 体 的 Set 类 但 正 式 的 集 概 念 却 比 Java 技 术 提 前 了 一 个 世 纪, 那 时 英 国 数 学 家 George Boole 按 逻 辑 正 式 的 定 义 了 集 的 概 念 大 部 分 人 在 小 学 时 通 过 我 们 熟 悉 的 维 恩 图 引 入 的 集 的 交 和 集 的 并 学 到 过 一 些 集 的 理 论 映 射 是 一 种 特 别 的 集 它 是 一 种 对 (pair) 集, 每 个 对 表 示 一 个 元 素 到 另 一 元 素 的 单 向 映 射 一 些 映 射 示 例 有 : 字 典 ( 词 到 含 义 的 映 射 ) 关 键 字 到 数 据 库 记 录 的 映 射 IP 地 址 到 域 名 (DNS) 的 映 射 2 进 制 到 10 进 制 转 换 的 映 射 什 么 是 集 合 集 合 是 包 含 多 个 对 象 的 简 单 对 象, 所 包 含 的 对 象 称 为 元 素 集 合 的 典 型 应 用 是 用 来 处 理 多 种 第 199 页

200 类 型 的 对 象, 这 些 类 型 必 须 有 共 同 的 父 类 集 合 框 架 由 一 组 用 来 操 作 对 象 的 接 口 组 成 不 同 接 口 描 述 不 同 类 型 的 组 在 很 大 程 度 上, 一 旦 你 理 解 了 接 口, 就 理 解 了 框 架 虽 然 总 要 创 建 接 口 特 定 的 实 现, 但 访 问 实 际 集 合 的 方 法 应 该 限 制 在 接 口 方 法 的 使 用 上 ; 因 此, 允 许 更 改 基 本 的 数 据 结 构 而 不 必 改 变 其 它 代 码 框 架 接 口 层 次 结 构 如 下 图 所 示 Collection Map Set List HashSet TreeSet ArrayList LinkedList HashMap TreeMap 从 上 图 中, 我 们 可 以 看 出, 集 合 主 要 分 为 3 中 类 型 : k3 v k2 v2 3 2 k1 v1 Set( 集 ) List( 列 表 ) Map( 映 射 ) Set( 集 ) 中 的 对 象 不 允 许 重 复, 无 序 List( 列 表 ) 中 的 对 象 允 许 重 复, 有 序 允 许 按 照 对 象 在 集 合 中 的 索 引 位 置 检 索 对 象 List 与 数 组 有 些 相 似 Map( 映 射 ) 集 合 中 的 每 一 个 元 素 包 含 一 对 键 对 象 和 值 对 象, 集 合 中 没 有 重 复 的 键 对 象, 值 对 象 可 以 重 复 第 200 页

201 9.2 Collection 接 口 和 Iterator 接 口 在 Collection 接 口 中 声 明 了 适 用 于 Java 集 合 ( 只 包 含 Set 和 List) 的 通 用 方 法 : 方 法 描 述 boolean add(object o) 向 集 合 中 添 加 一 个 对 象 的 引 用 void clear() 删 除 集 合 中 所 有 的 对 象, 即 不 再 持 有 这 些 对 象 的 引 用 boolean contains(object o) 判 断 在 集 合 中 是 否 持 有 特 定 对 象 的 引 用 boolean isempty() 判 断 集 合 是 否 为 空 Iterator iterator() 返 回 一 个 Iterator 对 象, 可 用 它 来 遍 历 集 合 中 的 元 素 Boolean remove(object o) 从 集 合 中 删 除 一 个 对 象 的 引 用 int size() 返 回 集 合 中 元 素 的 数 目 Object[] toarray() 返 回 一 个 数 组, 该 数 组 包 含 集 合 中 所 有 的 元 素 Set 接 口 和 List 接 口 都 继 承 了 Collection 接 口, 而 Map 接 口 没 有 集 成 Collection 接 口, 因 此 可 以 对 Set 对 象 和 List 对 象 调 用 以 上 方 法, 但 是 不 能 对 Map 对 象 调 用 以 上 方 法 Collection 接 口 的 iterator() 和 toarray() 方 法 都 用 于 获 得 集 合 中 的 所 有 对 象, iterator() 方 法 返 回 一 个 Iterator 对 象,toArray() 方 法 返 回 一 个 包 含 集 合 中 所 有 元 素 的 数 组 Iterator 接 口 隐 藏 底 层 集 合 的 数 据 结 构, 向 客 户 程 序 提 供 了 遍 历 各 种 类 型 的 集 合 的 统 一 接 口 Iterator 接 口 中 声 明 了 如 下 方 法 : 方 法 描 述 boolean hasnext() 判 断 集 合 中 的 元 素 是 否 遍 历 完 毕, 如 果 没 有, 就 返 回 true Object next() 返 回 下 一 个 元 素 void remove() 从 集 合 中 删 除 上 一 个 由 next() 方 法 返 回 的 元 素 Collection 接 口 还 支 持 元 素 组 的 操 作 : 方 法 描 述 boolean containsall (Collection collection) 判 断 集 合 中 是 否 包 含 了 另 一 个 集 合 的 所 有 元 素, 即 另 一 个 集 合 是 否 是 当 前 集 合 的 子 集, 如 果 是, 就 返 回 true boolean addall (Collection collection) 将 另 一 个 集 合 中 的 所 有 元 素 都 添 加 到 当 前 的 集 合 中, 通 常 称 为 并 void removeall 类 似 于 clear(), 移 除 此 集 合 中 那 些 包 含 在 指 定 (Collection collection) collection 中 的 所 有 元 素 boolean retainall (Collection collection) 仅 保 留 此 集 合 中 那 些 也 包 含 在 指 定 collection 的 元 素, 即 交 集 第 201 页

202 9.3 Set( 集 ) Set 是 最 简 单 的 一 种 集 合, 集 合 中 的 对 象 不 按 特 定 的 方 式 排 序, 它 不 允 许 集 合 中 存 在 重 复 项 Set 接 口 主 要 有 两 个 实 现 类 :HashSet 和 TreeSet HashSet 按 照 哈 希 算 法 来 存 取 集 合 中 的 对 象, 存 取 速 度 比 较 快 Hash 类 还 有 一 个 子 类 LinkedHashSet 类, 它 不 仅 实 现 了 Hash 算 法, 而 且 实 现 了 链 表 数 据 结 构, 链 表 数 据 结 构 能 提 高 插 入 和 删 除 元 素 的 性 能 TreeSet 类 实 现 了 SortedSet 接 口, 具 有 排 序 功 能 Set 的 一 般 用 法 Set 集 合 中 存 放 的 是 对 象 的 引 用, 并 且 没 有 重 复 对 象 以 下 代 码 创 建 了 3 个 引 用 变 量 :s1 s2 s3 s2 和 s3 变 量 引 用 同 一 个 字 符 串 对 象 world, s1 变 量 引 用 另 一 个 字 符 串 对 象 hello,set 集 合 依 次 把 这 3 个 引 用 变 量 加 入 到 集 合 中 Set<String> set=new HashSet<String>(); String s1=new String("hello"); String s2=new String("world"); String s3=s2; set.add(s1); set.add(s2); set.add(s3); System.out.println(set.size());// 打 印 集 合 中 对 象 的 数 目 2 以 上 程 序 的 打 印 结 果 为 2, 实 际 上 只 向 Set 集 合 加 入 了 两 个 对 象, 引 用 变 量 set HashSet 对 象 hello 引 用 变 量 s1 world 引 用 变 量 s2 引 用 变 量 s3 当 一 个 新 对 象 加 入 到 Set 集 合 中 时,Set 采 用 对 象 的 equals() 方 法 比 较 两 个 对 象 是 否 相 等, 而 不 是 采 用 == 比 较 运 算 符 所 以 实 际 上 只 向 集 合 中 加 入 了 一 个 对 象 HashSet 类 HashSet 类 按 照 哈 希 算 法 来 存 取 集 合 中 的 对 象, 具 有 很 好 的 存 取 和 查 找 性 能 当 向 集 合 中 加 入 一 个 对 象 时,HashSet 会 调 用 对 象 的 hashcode() 方 法 来 获 得 哈 希 码, 然 后 根 据 这 个 哈 希 码 进 一 步 计 算 出 对 象 在 集 合 中 的 存 放 位 置 在 object 类 中 定 义 了 hashcode() 和 equals() 方 法,Object 类 的 equals() 方 法 按 照 内 存 地 址 比 较 对 象 是 否 相 等, 因 此 如 果 object1.equals(object2) 为 true, 则 表 明 object1 和 object2 变 量 实 际 上 引 用 同 一 个 对 象, 那 么 两 个 对 象 的 哈 希 码 也 肯 定 相 等 第 202 页

203 如 果 用 户 定 义 的 Customer 类 覆 盖 了 Object 类 的 equals() 方 法, 但 是 没 有 覆 盖 Object 类 的 hashcode() 方 法, 就 会 导 致 customer1.equals(customer2) 为 true 时, 而 customer1 和 customer2 的 哈 希 码 不 一 定 一 样, 这 会 使 HashSet 无 法 正 常 工 作 class Customer{ private String name; private int age; // 省 略 set get 方 法 public Customer(String name,int age){ this.name=name; this.age=age; public boolean equals(object obj) { if (this == obj) { return true; if (obj == null) { return false; if (obj instanceof Customer) { Customer customer = (Customer) obj; if (this.name.equals(customer.getname()) && this.age==customer.getage()) { return true; else { return false; else { return false; 以 下 程 序 向 HashSet 中 加 入 两 个 Customer 对 象 Set<Customer> set=new HashSet<Customer>(); Customer customer1=new Customer("Tom",25); Customer customer2=new Customer("Tom",25); set.add(customer1); set.add(customer2); System.out.println(set.size()); 由 于 customer1.equals(customer2) 的 比 较 结 果 为 true, 按 理 说 HashSet 只 应 该 把 customer1 加 入 集 合 中, 但 实 际 上 以 上 程 序 的 打 印 结 果 为 2, 表 明 集 合 中 加 入 了 两 个 对 象 出 现 这 一 非 正 常 现 象 在 于,customer1 和 customer2 的 哈 希 码 不 一 样, 因 此 HashSet 为 customer1 和 customer2 计 算 出 不 同 的 存 放 位 置, 于 是 把 它 们 存 放 在 集 合 中 的 不 同 地 方 为 了 保 证 HashSet 正 常 工 作, 如 果 Customer 类 覆 盖 了 equals() 方 法, 也 应 该 覆 盖 hashcode() 方 法, 并 且 保 证 两 个 相 等 的 Customer 对 象 的 哈 希 码 也 一 样 Customer 类 的 hashcode() 方 法 代 码 如 下 : 第 203 页

204 public int hashcode(){ int result; result=(name==null?0:name.hashcode()); result=29*result+age; return result; 判 断 name 是 否 为 null 是 为 了 保 证 程 序 代 码 的 健 壮 性 TreeSet 类 TreeSet 类 实 现 了 SortedSet 接 口, 能 够 对 集 合 中 的 对 象 进 行 排 序 以 下 程 序 创 建 了 一 个 TreeSet 对 象, 然 后 向 集 合 中 加 入 4 个 Integer 对 象 Set<Integer> set = new TreeSet<Integer>(); set.add(new Integer(3)); set.add(new Integer(1)); set.add(new Integer(4)); set.add(new Integer(2)); Iterator<Integer> it=set.iterator(); while(it.hasnext()){ System.out.print(it.next()+" "); 以 上 程 序 的 打 印 结 果 为 : 当 treeset 向 集 合 中 加 入 一 个 对 象 时, 会 把 它 插 入 到 有 序 的 对 象 序 列 中 那 么 TressSet 是 如 何 对 对 象 进 行 排 序 的 呢?TreeSet 支 持 两 种 排 序 方 式 : 自 然 排 序 和 客 户 化 排 序 在 默 认 情 况 下 TreeSet 采 用 自 然 排 序 方 式 自 然 排 序 在 JDK 类 库 中, 有 一 部 分 类 实 现 Comparable 接 口, 如 Integer Double 和 String 等 Comparable 接 口 有 一 个 compareto(object o) 方 法, 它 返 回 整 数 类 型 对 于 表 达 式 x.compareto(y), 如 果 返 回 值 为 0, 则 表 示 x 和 y 相 等, 如 果 返 回 值 大 于 0, 则 表 示 x 大 于 y, 如 果 返 回 值 小 于 0, 则 表 示 x 小 于 y TreeSet 调 用 对 象 的 compareto() 方 法 比 较 集 合 中 对 象 的 大 小, 然 后 进 行 升 序 排 列, 这 种 排 序 方 式 称 为 自 然 排 序 下 表 中 显 示 了 JDK 类 库 中 实 现 了 Comparable 接 口 的 一 些 类 的 排 序 方 式 类 BigDecimal BigInteger Byte Float Integer Long Short Character 按 数 字 大 小 排 序 排 序 按 字 符 的 Unicode 值 的 数 字 大 小 排 序 第 204 页

205 String 按 字 符 串 中 字 符 的 Unicode 值 排 序 使 用 自 然 排 序 时, 只 能 向 TreeSet 集 合 中 加 入 同 类 型 的 对 象, 并 且 这 些 对 象 的 类 必 须 实 现 Comparable 接 口 以 下 程 序 先 后 向 TreeSet 集 合 中 加 入 了 一 个 Integer 对 象 和 String 对 象 Set<Object> set = new TreeSet<Object>(); set.add(new Integer(3)); set.add(new String("1"));// 运 行 时 抛 出 ClassCastException 当 第 二 次 调 用 TreeSet 的 add() 方 法 时 抛 出 ClassCastException Exception in thread "main" java.lang.classcastexception: java.lang.integer cannot be cast to java.lang.string at java.lang.string.compareto(string.java:92) at java.util.treemap.put(treemap.java:545) at java.util.treeset.add(treeset.java:238) at Client.main(Client.java:17) 在 string 类 的 compareto(object o) 方 法 中, 首 先 对 参 数 o 进 行 类 型 转 换 String s=(string)o; 如 果 参 数 o 实 际 引 用 的 不 是 String 类 型 的 对 象, 以 上 代 码 就 会 抛 出 ClassCastException 下 面 的 示 例 中 向 TreeSet 集 合 加 入 了 3 个 Customer 对 象, 但 是 Customer 类 没 有 实 现 Comparable 接 口 Set<Customer> set = new TreeSet<Customer>(); set.add(new Customer("Tom",25)); set.add(new Customer("Tom",24)); set.add(new Customer("Jim",25)); 当 第 二 次 调 用 TreeSet 的 add() 方 法 时, 也 会 抛 出 ClassCastException 异 常 如 果 希 望 避 免 这 种 异 常, 应 该 使 Customer 类 实 现 Comparable 接 口 class Customer implements Comparable{ private String name; private int age; // 省 略 set get 方 法 public Customer(String name, int age) { this.name = name; this.age = age; public int compareto(object o){ Customer other=(customer)o; // 先 按 照 name 属 性 排 序 if(this.name.compareto(other.getname())>0){ return 1; 第 205 页

206 else if(this.name.compareto(other.getname())<0){ return -1; // 再 按 照 age 属 性 排 序 if(this.age>other.getage()){ return 1; else if(this.age<other.getage()){ return -1; return 0; public boolean equals(object obj) { if (this == obj) { return true; if (obj == null) { return false; if (obj instanceof Customer) { Customer customer = (Customer) obj; if (this.name.equals(customer.getname()) && this.age == customer.getage()) { return true; else { return false; else { return false; public int hashcode(){ int result; result=(name==null?0:name.hashcode()); result=29*result+age; return result; 为 了 保 证 TreeSet 能 正 确 排 序, 要 求 Customer 类 的 compareto() 方 法 与 equals 方 法 按 相 同 的 规 则 比 较 两 个 Customer 对 象 是 否 相 等 也 就 是 说, 如 果 customer1.equals(customer2) 为 true, 那 么 customer1.compareto(customer2) 为 0 测 试 代 码 如 下 : Set<Customer> set = new TreeSet<Customer>(); set.add(new Customer("Tom",25)); set.add(new Customer("Tom",24)); 第 206 页

207 set.add(new Customer("Jim",25)); Iterator<Customer> it=set.iterator(); while(it.hasnext()){ Customer customer=it.next(); System.out.println(customer.getName()+" "+customer.getage()); 打 印 结 果 为 : Jim 25 Tom 24 Tom 客 户 化 排 序 除 了 自 然 排 序,TreeSet 还 支 持 客 户 化 排 序 使 用 Java.util.Comparator<Type> 接 口 提 供 具 体 的 排 序 方 式,<Type> 指 定 被 比 较 的 对 象 的 类 型,Comparator 有 个 compare(type x,type y) 方 法, 用 于 比 较 两 个 对 象 的 大 小 当 compare(x,y) 的 返 回 值 大 于 0 时, 表 示 x 大 于 y; 当 compare(x,y) 的 返 回 值 小 于 0 时, 表 示 x 小 于 y; 当 compare(x,y) 的 返 回 值 等 于 0 时, 表 示 x 等 于 y 如 果 希 望 TreeSet 按 照 Customer 对 象 的 name 属 性 进 行 降 序 排 列, 可 以 先 创 建 一 个 实 现 Comparator 接 口 的 类 CustomerComparator import java.util.comparator; import java.util.iterator; import java.util.set; import java.util.treeset; public class CustomerComparator implements Comparator<Customer>{ public int compare(customer c1, Customer c2) { if(c1.getname().compareto(c2.getname())>0){ return -1; else if(c1.getname().compareto(c2.getname())<0){ return 1; return 0; public static void main(string[] args){ Set<Customer> set = new TreeSet<Customer>(new CustomerComparator()); set.add(new Customer("Tom",25)); set.add(new Customer("Tom",24)); set.add(new Customer("Jim",25)); Iterator<Customer> it=set.iterator(); while(it.hasnext()){ Customer customer=it.next(); System.out.println(customer.getName()+" "+customer.getage()); 第 207 页

208 当 treeset 向 集 合 中 加 入 Customer 对 象 时, 会 调 用 CustomerComparator 类 的 compare() 方 法 进 行 排 序 以 上 TreeSet 按 照 Customer 对 象 的 name 属 性 进 行 降 序 排 列, 最 后 打 印 结 果 为 : Tom 25 Jim 25 因 为 compare() 方 法 使 用 Customer 对 象 的 name 属 性 进 行 比 较,set 集 合 只 保 存 了 第 一 个 Tom 9.4 List( 列 表 ) List 的 主 要 特 征 是 其 元 素 以 线 性 方 式 存 储, 集 合 中 允 许 存 放 重 复 对 象 list 接 口 主 要 的 实 现 类 包 括 : ArrayList--ArrayList 代 表 长 度 可 变 的 数 组 允 许 对 元 素 进 行 快 速 的 随 机 访 问, 但 是 向 ArrayList 中 插 入 与 删 除 元 素 的 速 度 较 慢 LinkedList 在 实 现 中 采 用 链 表 数 据 结 构 对 顺 序 访 问 进 行 优 化, 向 List 中 插 入 和 删 除 元 素 的 速 度 较 快, 随 机 访 问 速 度 则 相 对 较 慢 随 机 访 问 是 指 检 索 位 于 特 定 索 引 位 置 的 元 素 LinkedList 单 独 具 有 addfirst() addlast() getfirst() getlast() removefirst() 和 removelast() 方 法, 这 些 方 法 使 得 LinkedList 可 以 作 为 堆 栈 队 列 和 双 向 队 列 来 使 用 访 问 列 表 的 元 素 List 中 的 对 象 按 照 索 引 位 置 排 序, 客 户 程 序 可 以 按 照 对 象 在 集 合 中 的 索 引 位 置 来 检 索 对 象 以 下 程 序 向 List 中 加 入 4 个 Integer 对 象 List<Integer> list = new ArrayList<Integer>(); list.add(new Integer(3)); list.add(new Integer(2)); list.add(new Integer(1)); list.add(new Integer(2)); List 的 get(int index) 方 法 返 回 集 合 中 由 参 数 index 指 定 的 索 引 位 置 的 对 象, 第 一 个 加 入 到 集 合 中 的 对 象 的 索 引 位 置 为 0, 依 次 类 推 以 下 程 序 依 次 检 索 出 集 合 中 的 所 有 对 象 for(int i=0;i<list.size();i++){ System.out.print(list.get(i)+" "); 以 上 程 序 的 打 印 结 果 为 : List 的 iterator() 方 法 和 Set 的 iterator() 方 法 一 样, 也 能 返 回 Iterator 对 象, 可 第 208 页

209 以 用 Iterator 来 遍 历 集 合 中 的 所 有 对 象, 例 如 : Iterator<Integer> it=list.iterator(); while(it.hasnext()){ System.out.print(it.next()); 为 列 表 排 序 List 只 能 对 集 合 中 的 对 象 按 索 引 位 置 排 序, 如 果 希 望 对 List 中 的 对 象 按 其 他 特 定 的 方 式 排 序, 可 以 借 助 Comparator 接 口 和 Collections 类 Collections 类 是 Java 集 合 类 库 中 的 辅 助 类, 它 提 供 了 操 作 集 合 的 各 种 静 态 方 法, 其 中 sort() 方 法 用 于 对 List 中 的 对 象 进 行 排 序 sort(list list): 对 List 中 的 对 象 进 行 自 然 排 序 sort(list list,comparator comparator): 对 List 中 的 对 象 进 行 客 户 化 排 序, comparator 参 数 指 定 排 序 方 式 以 下 程 序 对 List 中 的 Integer 对 象 进 行 自 然 排 序 List<Integer> list = new ArrayList<Integer>(); list.add(new Integer(3)); list.add(new Integer(2)); list.add(new Integer(1)); list.add(new Integer(2)); Collections.sort(list); for(int i=0;i<list.size();i++){ System.out.print(list.get(i)+" "); 以 上 程 序 的 打 印 结 果 为 : ListIterator 接 口 List 的 listiterator() 方 法 返 回 一 个 ListIterator 对 象,ListIterator 接 口 继 承 了 Iterator 接 口, 此 外 还 提 供 了 专 门 操 作 列 表 的 方 法 add(): 向 列 表 中 插 入 一 个 元 素 hasnext(): 判 断 列 表 中 是 否 还 有 下 一 个 元 素 HasPrevious(): 判 断 列 表 中 是 否 还 有 上 一 个 元 素 第 209 页

210 next(): 返 回 列 表 中 的 下 一 个 元 素 previous(): 返 回 列 表 中 的 上 一 个 元 素 下 面 示 例 中 的 insert() 方 法 向 一 个 排 序 的 List 列 表 中 按 顺 序 插 入 数 据 class ListInserter { // 向 List 列 表 中 按 顺 序 插 入 元 素 public static void insert(list<integer> list,int data) { ListIterator<Integer> it=list.listiterator(); while(it.hasnext()){ Integer in=it.next(); if(data<=in.intvalue()){ // 指 针 向 前 移 动 it.previous(); // 插 入 元 素 it.add(new Integer(data)); break; public static void main(string[] args){ // 创 建 一 个 链 接 列 表 List<Integer> list = new ArrayList<Integer>(); list.add(new Integer(3)); list.add(new Integer(5)); list.add(new Integer(1)); list.add(new Integer(2)); // 为 列 表 排 序 Collections.sort(list); // 向 列 表 中 插 入 一 个 元 素 insert(list,4); System.out.print(Arrays.toString(list.toArray())); 以 上 程 序 的 打 印 结 果 如 下 : [1, 2, 3, 4, 5] 获 得 固 定 长 度 的 List 对 象 Java.util.Arrays 类 的 aslist() 方 法 能 够 把 一 个 Java 数 据 包 装 成 一 个 List 对 象, 这 个 List 对 象 代 表 固 定 长 度 的 数 组 所 有 对 List 对 象 的 操 作 都 会 被 作 用 到 底 层 的 Java 数 组 由 于 数 组 的 长 度 不 能 改 变, 因 此 不 能 调 用 这 种 List 对 象 的 add() 和 remove() 方 法, 否 则 就 会 抛 出 java.lang.unsupportedoperationexception 运 行 时 异 常 String[] arr={"smith","tom","jack"; 第 210 页

211 List<String> list=arrays.aslist(arr); list.set(1, "jane"); // 合 法, 可 以 修 改 某 个 位 置 的 元 素 System.out.println(Arrays.toString(arr)); // 打 印 [Smith, jane, Jack] list.remove("tom");// 非 法, 抛 出 UnsupportedOperationException list.add("mary");// 非 法, 抛 出 UnsupportedOperationException 比 较 Java 数 组 和 各 种 List 的 性 能 List 的 两 个 实 现 类 ArrayList 和 LinkedList 都 表 示 列 表, 在 JDK1.0 版 本 中 有 一 个 Vector 类, 也 表 示 列 表, 在 JDK1.2 版 本 中 把 Vector 类 改 为 实 现 了 List 接 口 分 别 对 Java 数 组 ArrayList LinkedList Vector 进 行 测 试, 测 试 的 数 据 量 是 10 万 条 数 据, 次 数 是 10 万 次 测 试 结 果 如 下 ( 单 位 : 毫 秒 ): 类 型 Java 数 组 ArrayList LinkedList Vector 随 机 访 问 操 作 (get) 迭 代 操 作 (iterator) 插 入 操 作 (insert) 不 适 用 删 除 操 作 (remove) 不 适 用 总 结 如 下 :ArrayList 的 效 率 相 对 平 衡, 对 LinkedList 进 行 操 作, 因 为 要 先 进 行 顺 序 查 找, 所 以 效 率 较 低,Vector 类 在 各 方 面 的 性 能 也 不 是 太 差, 属 于 历 史 集 合 类, 已 经 不 提 倡 使 用 它 9.5 Map( 映 射 ) Map( 映 射 ) 是 一 种 把 键 对 象 和 值 对 象 进 行 映 射 的 集 合, 它 的 每 一 个 元 素 都 包 含 一 对 键 对 象 和 值 对 象, 而 值 对 象 仍 可 以 是 Map 类 型, 以 此 类 推, 这 样 就 形 成 了 多 级 映 射 向 Map 集 合 中 加 入 元 素 时, 必 须 提 供 一 对 键 对 象 和 值 对 象, 从 Map 集 合 中 检 索 元 素 时, 只 要 给 出 键 对 象, 就 会 返 回 对 应 的 值 对 象 以 下 程 序 通 过 Map 的 put(object key,object value) 方 法 向 集 合 中 加 入 元 素, 通 过 Map 的 get(obejct key) 方 法 来 检 索 与 键 对 象 对 应 的 值 对 象 Map<String,String> map=new HashMap<String,String>(); map.put("1", "Monday"); map.put("2", "Tuesday"); map.put("3", "Wendsday"); map.put("4", "Thursday"); String day=map.get("2");//day 的 值 为 "Tuesday" Map 集 合 中 的 键 对 象 不 允 许 重 复, 也 就 是 说 任 意 两 个 键 对 象 通 过 equals() 方 法 比 较 的 结 果 都 是 false 对 于 值 对 象 则 没 有 唯 一 性 的 要 求, 可 以 将 任 意 多 个 键 对 象 映 射 到 一 个 值 对 象 上 例 如 以 下 Map 集 合 中 的 键 对 象 1 和 one 都 和 同 一 个 值 对 象 Monday 对 应 Map<String,String> map=new HashMap<String,String>(); map.put("1", "Mon"); map.put("1", "Monday"); map.put("one", "Monday"); 第 211 页

212 Set<String> set=map.keyset(); Iterator<String> it=set.iterator(); while(it.hasnext()){ String key=it.next(); String value=map.get(key); System.out.println("key="+key+",value="+value); 由 于 第 一 次 和 第 二 次 加 入 Map 中 的 键 对 象 都 为 1, 因 此 第 一 次 加 入 的 值 对 象 将 被 覆 盖, Map 集 合 中 最 后 只 有 两 个 元 素, 分 别 为 : 1--->Monday one--->monday Map 的 keyset() 方 法 返 回 集 合 中 所 有 键 对 象 的 集 合 Map 有 两 种 比 较 常 用 的 实 现 :HashMap 和 TreeMap HashMap 按 照 哈 希 算 法 来 存 取 键 对 象, 有 很 好 的 存 取 性 能, 为 了 保 证 HashMap 能 正 常 工 作, 和 HashSet 一 样, 要 求 当 两 个 键 对 象 通 过 equals() 方 法 比 较 为 true 时, 这 两 个 键 对 象 的 hashcode() 方 法 返 回 的 哈 希 码 也 一 样 TreeMap 实 现 了 SortedMap 接 口, 能 对 键 对 象 进 行 排 序 和 TreeSet 一 样,TreeMap 也 支 持 自 然 排 序 和 客 户 化 排 序 两 种 方 式 以 下 程 序 中 TreeMap 会 对 4 个 String 类 型 的 键 对 象 进 行 自 然 排 序 Map<String,String> map=new TreeMap<String,String>(); map.put("3", "Wendsday"); map.put("1", "Monday"); map.put("4", "Thursday"); map.put("2", "Tuesday"); Set<String> set=map.keyset(); Iterator<String> it=set.iterator(); while(it.hasnext()){ String key=it.next(); String value=map.get(key); System.out.println("key="+key+",value="+value); 以 上 程 序 的 打 印 结 果 为 : key=1,value=monday key=2,value=tuesday key=3,value=wendsday key=4,value=thursday 如 果 希 望 TreeMap 对 键 对 象 进 行 客 户 化 排 序, 可 调 用 它 的 另 一 个 构 造 方 法 ---TreeMap(Comparator comparator), 参 数 comparator 指 定 具 体 的 排 序 方 式 第 212 页

213 9.6 历 史 集 合 类 Collection Set List HashSet TreeSet ArrayList LinkedList Vector Map HashMap TreeMap Propertie HashTable 在 早 期 的 JDK1.0 版 本 中, 代 表 集 合 的 类 只 有 Vector Stack Enumeration Hashtable Properties 和 BitSet 从 JDK1.2 版 本 开 始, 才 出 现 了 Collection Set List 和 Map 接 口 及 各 种 实 现 类, 它 们 构 成 了 完 整 的 Java 集 合 框 架 JDK1.0 版 本 中 的 集 合 类 也 称 为 历 史 集 合 类 s 历 史 集 合 类 描 述 缺 点 替 代 类 Vector 集 合 中 的 元 素 有 索 引 位 置, 在 新 的 集 合 框 架 中 把 它 改 为 实 现 了 List 接 口 采 用 了 同 步 机 制, 影 响 操 纵 集 合 的 性 能 ArrayList LinkedList Stack 表 示 堆 栈, 支 持 后 进 先 出 的 操 采 用 了 同 步 机 制, 影 响 操 作 集 LinkedList 作 合 的 性 能 ;Stack 继 承 了 Vector 类, 使 得 Stack 不 能 作 为 严 格 的 堆 栈, 还 允 许 随 机 访 问 Hashtable 集 合 中 的 每 个 元 素 包 含 一 对 键 采 用 了 同 步 机 制, 影 响 操 作 集 HashMap 与 值 在 新 的 集 合 框 架 中 把 它 改 为 实 现 了 Map 接 口 合 的 性 能 Properties 集 合 中 的 每 个 元 素 包 含 一 对 键 采 用 了 同 步 机 制, 影 响 操 作 集 无 第 213 页

214 Enumeratio n BitSet 与 值, 继 承 了 Hashtable 合 的 性 能 用 于 遍 历 集 合 中 的 元 素 只 能 与 Vector 和 Hashtable 等 历 史 集 合 配 套 使 用 ;Enumeration 类 的 名 字 较 长,Iterator 类 的 名 字 简 短 存 放 一 组 boolean 类 型 无 数 据, 支 持 与 或 和 异 或 操 作 Iterator 无 9.7 数 据 结 构 ( 可 选 ) 线 性 表 线 性 表 (List) 是 由 叫 作 元 素 (Element) 的 数 据 项 组 成 的 一 种 有 限 并 且 有 序 的 序 列 有 序 是 指 线 性 表 中 的 每 一 个 元 素 都 有 自 己 的 位 置 (index) 线 性 表 中 的 元 素 有 相 同 的 类 型 ; 线 性 表 中 不 包 含 任 何 元 素 时, 我 们 称 之 为 空 表 (empty List); 当 前 实 际 存 储 的 元 素 数 据 的 个 数 叫 做 线 性 表 的 长 度 (length); 线 性 表 的 开 始 节 点 ( 第 一 个 元 素 ) 叫 作 表 头 (head); 线 性 表 的 结 尾 节 点 ( 最 后 一 个 元 素 ) 叫 作 表 尾 (tail); 如 果 线 性 表 的 元 素 按 照 值 的 递 增 顺 序 排 列, 我 们 称 之 为 有 序 线 性 表 (sorted list); 如 果 线 性 表 的 元 素 与 位 置 没 有 关 系, 我 们 称 之 为 无 序 线 性 表 (unsorted list); 线 性 表 的 表 示 :(a 0,a 1,a 2,,a n-1 ) 线 性 表 的 操 作 public interface List { //remove all Objects from list public void clear(); //insert Object at current position public void insert(object item); //insert Object at tail of list public void append(object item); 第 214 页

215 //remove/return current Object public Object remove(); //set current to first position public void setfirst(); //move current to next position public void next(); //move current to prev position public void prev(); //return current length of list public int length(); //set current to specified pos public void setpost(int pos); //set current Object's value public void setvalue(object val); //return value of current Object public Object currvalue(); //return true if list is empty public boolean isempty(); //return true if current is within list public boolean isinlist(); //print all of list's elements public void print(); 线 性 表 有 两 种 标 准 的 实 现 方 法 : 顺 序 表 (array-based list) 和 链 表 (linked list) 顺 序 表 顺 序 表 的 实 现 是 用 数 组 来 存 储 表 中 的 元 素, 这 就 意 味 着 将 要 分 配 固 定 长 度 的 数 组 因 此 当 线 性 表 生 成 时 数 组 的 长 度 必 须 是 已 知 的 既 然 每 个 线 性 表 可 以 有 一 个 不 等 长 的 数 组, 那 么 这 个 长 度 就 必 须 由 线 性 表 对 象 来 记 录 在 任 何 给 定 的 时 刻, 线 性 表 都 有 一 定 数 目 的 元 素, 这 个 数 目 应 该 小 于 数 组 允 许 的 最 大 值 线 性 表 中 当 前 的 实 际 元 素 数 目 也 必 须 在 线 性 表 中 记 录 顺 序 表 把 表 中 的 元 素 存 储 在 数 组 中 相 邻 的 位 置 上 数 组 的 位 置 与 元 素 的 位 置 相 对 应 换 句 话 说, 就 是 表 中 第 i 个 元 素 存 储 在 数 组 的 第 i 个 单 元 中 表 头 总 是 在 第 0 个 位 置, 这 就 使 得 对 表 中 任 意 一 个 元 素 的 随 机 访 问 相 当 容 易 给 出 表 中 的 某 一 个 位 置, 这 个 位 置 对 应 元 素 的 值 就 可 以 直 接 获 取 第 215 页

216 如 果 在 表 尾 进 行 插 入 和 删 除 操 作 很 方 便 ; 如 果 在 表 中 插 入 一 个 元 素, 就 要 将 此 元 素 之 后 的 所 有 元 素 向 后 移 动 一 个 位 置 ; 如 果 在 表 中 删 除 一 个 元 素, 就 要 将 此 元 素 之 后 的 所 有 元 素 向 前 移 动 一 个 位 置 public class ArrayList implements List { // default array size private static final int defaultsize = 10; // max size of list private int maxsize; // actual number of Objects in list private int length; // position of current Object private int curr; // Array holding list Objects private Object[] listarray; /** * Constructor use default size */ public ArrayList() { setup(defaultsize); /** * Constructor use specified size */ public ArrayList(int size) { setup(size); private void setup(int size) { maxsize = size; length = curr = 0; listarray = new Object[size]; //remove all Objects from list public void clear(){ length = curr = 0; //insert Object at current position public void insert(object item){ if (isfull()){ throw new RuntimeException(" 顺 序 表 达 到 最 大 容 量 "); for(int i=length;i>curr;i--){ 第 216 页

217 listarray[i]=listarray[i-1]; listarray[curr]=item; length++; //insert Object at tail of list public void append(object item){ if (isfull()){ throw new RuntimeException(" 顺 序 表 达 到 最 大 容 量 "); listarray[length] = item; length++; //remove/return current Object public Object remove(){ if (isempty()){ throw new RuntimeException(" 顺 序 表 为 空, 无 法 再 删 除 了 "); Object o=listarray[curr]; for(int i=curr;i<length-1;i++){ listarray[i]=listarray[i+1]; length--; return o; //set current to first position public void setfirst(){ curr=0; //move current to next position public void next(){ curr++; //move current to prev position public void prev(){ curr--; //return current length of list public int length(){ return length; //set current to specified post 第 217 页

218 public void setpost(int pos){ curr=pos; //set current Object's value public void setvalue(object val){ listarray[curr]=val; //return value of current Object public Object currvalue(){ return listarray[curr]; //return true if list is empty public boolean isempty(){ if(length==0) { return true; else { return false; //return true if list is full public boolean isfull(){ if (length == maxsize){ return true; else{ return false; //return true if current is within list public boolean isinlist(){ return curr>=0 && curr<length; //print all of list's elements public void print(){ if(isempty()){ System.out.println("[]"); else{ System.out.print("["); for(setfirst();isinlist();next()){ System.out.print(currValue()+" "); System.out.print("]"); 第 218 页

219 链 表 间 链 表 是 利 用 指 针 来 实 现 的, 是 动 态 的, 也 就 是 说, 能 够 按 照 需 要 为 表 中 新 的 元 素 分 配 存 储 空 链 表 是 由 一 系 列 叫 作 结 点 的 对 象 组 成, 每 一 个 结 点 都 是 一 个 独 立 的 对 象 下 面 代 码 中 表 示 了 结 点 的 完 整 定 义,Link 类 包 含 一 个 存 储 单 元 值 的 element 属 性 和 一 个 存 储 表 中 下 一 个 结 点 指 针 的 next 属 性 因 为 在 这 种 结 点 建 立 的 链 表 中, 每 个 结 点 只 有 一 个 指 向 表 中 下 一 个 节 点 的 指 针, 所 以 叫 作 单 链 表 (singly linked list) public class Link { //object for this node private Object element; //pointer to next node in list private Link next; Link(Object element,link next){ this.element=element; this.next=next; Link(Link next){ this.next=next; Link next(){ return next; Link setnext(link next){ this.next=next; return next; Object element(){ return element; Object setelement(object element){ return this.element=element; Link 类 非 常 简 单 它 有 两 个 构 造 方 法, 一 个 有 初 始 化 元 素 的 值, 另 一 个 没 有 其 他 方 法 帮 助 用 户 很 方 便 的 访 问 两 个 私 有 数 据 成 员 单 链 表 类 的 实 现 代 码 如 下 : public class LinkList implements List{ //pointer to list header private Link head; //pointer to last Object in list 第 219 页

220 private Link tail; //pointer to current Object protected Link curr; public LinkList(){ tail=head=curr=new Link(null); //remove all Objects from list public void clear(){ head.setnext(null); curr=tail=head; //insert Object at current position public void insert(object item){ curr.setnext(new Link(item,curr.next())); if(tail==curr){ tail=curr.next(); //insert Object at tail of list public void append(object item){ tail.setnext(new Link(item,null)); tail=tail.next(); //remove/return current Object public Object remove(){ if(!isinlist()){ throw new RuntimeException(" 当 前 节 点 为 null"); Object o=curr.element(); if(null==curr.next()){ prev(); curr.setnext(null); tail=curr; else{ Link temp= curr.next(); prev(); curr.setnext(temp); return o; //set current to first position public void setfirst(){ curr=head.next(); 第 220 页

221 //move current to next position public void next(){ if(curr!=null){ curr=curr.next(); //move current to prev position public void prev(){ if(curr==null curr==head){ //no previous object return; //so just return Link temp=head; //start at front of list while(temp!=null && temp.next()!=curr){ temp=temp.next(); curr=temp; //found previous link //return current length of list public int length(){ int count=0; for(link temp=head.next();temp!=null;temp=temp.next()){ count++; return count; //set current to specified post public void setpost(int pos){ curr=head; for(int i=0;curr!=null && i<pos;i++){ curr=curr.next(); //set current Object's value public void setvalue(object val){ if(isinlist()){ curr.setelement(val); else{ throw new RuntimeException(" 当 前 节 点 为 null"); //return value of current Object public Object currvalue(){ 第 221 页

222 if(curr==null){ return null; return curr.element(); //return true if list is empty public boolean isempty(){ return head.next()==null; //return true if current is within list public boolean isinlist(){ return curr!=null && curr.next()!=null; //print all of list's elements public void print(){ if(isempty()){ System.out.println("[]"); else{ System.out.print("["); for(setfirst();isinlist();next()){ System.out.print(currValue()+ " " ); System.out.println("]"); 单 链 表 中 增 加 了 特 殊 的 表 态 结 点, 这 个 表 头 结 点 是 表 中 的 第 一 个 结 点, 它 与 表 中 其 他 元 素 一 样, 只 是 它 的 值 被 忽 略, 不 被 看 做 表 中 的 实 际 元 素 这 样 我 们 就 不 再 需 要 考 虑 空 链 表, 表 中 一 定 有 一 个 结 点, 这 样 的 设 计 节 省 了 源 代 码, 降 低 了 源 程 序 的 复 杂 性 存 储 结 构 如 下 : curr tail head 空 的 单 链 表 ( 只 有 表 头 元 素 ) 当 使 用 append 方 法 向 表 中 添 加 新 的 元 素 时, 只 需 要 改 变 tail 指 向 结 点 的 next 属 性, 将 新 的 节 点 赋 值 给 该 属 性 即 可 第 222 页

223 head curr tail append 方 法 添 加 新 元 素 4 2 当 使 用 insert 方 法 时, 向 curr 指 向 的 结 点 后 添 加 一 个 新 的 节 点 head curr tail insert 方 法 添 加 新 元 素 6 3 当 使 用 remove 方 法 时, 将 curr 指 向 的 结 点 删 除, 如 果 curr 指 向 尾 结 点, 将 curr 指 针 向 前 移 动, 设 置 next 指 向 空 ; 如 果 curr 不 指 向 尾 结 点, 取 出 curr 的 下 一 个 结 点 temp, 将 curr 指 针 向 前 移 动, 设 置 curr 指 针 的 next 为 temp 结 点 head curr tail 删 前 除 head curr tail 4 2 删 后 除 当 curr 指 向 尾 结 点 时 使 用 remove 方 法 第 223 页

224 head curr tail 删 前 除 head curr tail 2 删 后 除 当 curr 没 有 指 向 尾 结 点 时 使 用 remove 方 法 注 : 代 码 中 设 计 删 除 当 前 结 点 后, 指 针 向 前 移 动 ; 也 可 以 设 计 成 删 除 结 点 后, 指 针 向 后 移 动 线 性 表 实 现 方 法 的 比 较 呢? 前 面 已 经 给 出 线 性 表 的 两 种 截 然 不 同 的 实 现 方 法, 哪 一 种 更 好 呢, 当 使 用 线 性 表 时 如 何 选 择 顺 序 表 的 缺 点 是 长 度 固 定 虽 然 便 于 给 数 组 分 配 空 间, 但 它 不 仅 不 能 超 过 预 定 的 长 度, 而 且 当 线 性 表 中 只 有 几 个 元 素 时, 浪 费 了 相 当 多 的 空 间 链 表 的 优 点 是 只 有 实 际 在 链 表 中 的 对 象 需 要 空 间 只 有 有 可 用 的 内 存 空 间 分 配, 链 表 中 元 素 的 个 数 就 没 有 限 制 顺 序 表 的 优 点 是 对 于 表 中 每 一 个 元 素 没 有 浪 费 空 间, 而 链 表 需 要 在 每 个 结 点 上 附 加 一 个 指 针 如 果 element 对 象 占 据 的 空 间 较 小, 则 链 表 的 结 构 性 开 销 就 占 去 了 整 个 存 储 空 间 的 一 大 部 分 当 顺 序 表 被 填 满 时, 存 储 上 没 有 结 构 性 开 销 这 这 种 情 况 下, 书 序 表 有 更 高 的 空 间 效 率 所 以 当 线 性 表 元 素 数 目 变 化 较 大 或 者 未 知 时, 最 好 使 用 链 表 实 现 而 如 果 用 户 事 先 知 道 线 性 表 的 大 致 长 度, 使 用 顺 序 表 的 空 间 效 率 会 更 高 当 要 求 对 线 性 表 进 行 随 机 访 问 时, 使 用 顺 序 表 更 快 一 些 ; 通 过 next 和 prev 只 可 以 调 整 当 前 位 置 向 前 或 向 后 移 动 其 中 next 操 作 很 容 易 实 现, 而 对 于 prev 操 作, 在 单 链 表 中 不 能 直 接 访 问 前 面 的 元 素, 只 能 从 表 头 开 始 寻 找 那 个 特 定 的 位 置 当 进 行 插 入 和 删 除 操 作 时, 链 表 比 顺 序 表 的 时 间 效 率 更 高 双 链 表 当 链 表 只 允 许 从 一 个 表 结 点 直 接 访 问 它 的 后 继 结 点, 而 双 链 表 (double linked list) 可 以 从 一 个 表 结 点 出 发, 方 便 地 再 线 性 表 中 访 问 它 的 前 驱 结 点 和 后 继 结 点 双 链 表 存 储 了 两 个 指 针, 一 个 指 向 它 的 后 继 结 点 ( 与 单 链 表 相 同 ), 另 一 个 指 向 它 的 前 驱 结 第 224 页

225 点 结 构 如 下 : head curr tail 双 链 表 结 构 3 4 双 链 表 比 单 链 表 更 容 易 实 现, 因 为 有 一 个 指 针 prev 可 以 访 问 前 一 个 结 点, 使 得 指 针 curr 先 前 或 向 后 移 动 变 得 非 常 方 便 栈 栈 (stack) 是 限 定 仅 在 一 端 进 行 插 入 或 删 除 的 线 性 表 虽 然 这 个 限 制 减 小 了 栈 的 灵 活 性, 但 是 会 使 栈 更 有 效 且 更 容 易 实 现 栈 的 访 问 遵 循 后 进 先 出 (last in first out) 原 则, 就 是 栈 的 可 访 问 元 素 为 栈 顶 (top) 元 素, 元 素 的 插 入 栈 称 作 压 栈 (push), 删 除 元 素 时 称 作 出 栈 (pop) 图 示 如 下 : 出 栈 进 栈 栈 顶 栈 底 1 思 考 题 : 如 果 进 栈 顺 序 为 , 那 么 下 面 哪 种 出 栈 顺 序 是 可 以 实 现 的? 两 种 常 用 实 现 方 法 : 顺 序 栈 (array-based stack) 和 链 式 栈 (linked stack) 队 列 同 栈 一 样, 队 列 (queue) 也 是 一 种 受 限 的 线 性 表 队 列 元 素 只 能 从 队 尾 插 入 ( 称 为 入 队 操 作 ), 从 队 首 进 行 删 除 ( 称 为 出 队 操 作 ) 队 列 操 作 就 像 在 电 影 院 前 排 队 买 票 一 样, 如 果 没 有 人 为 破 坏, 那 么 新 来 者 应 该 站 在 队 列 的 后 端, 在 队 列 最 前 端 的 人 是 下 一 个 要 被 服 务 的 对 象 第 225 页

226 队 列 的 访 问 遵 循 先 进 先 出 (first in first out) 原 则, 图 示 如 下 : 出 队 入 队 队 头 队 尾 两 种 常 用 实 现 方 法 : 顺 序 栈 (array-based queue) 和 链 式 栈 (linked queue) 9.8 学 习 目 标 1. 能 够 描 述 集 合 框 架 的 结 构 :Collection 接 口 List 接 口 Set 接 口 Map 接 口 及 实 现 类 2. 理 解 List 接 口 和 Set 接 口 的 特 点 3. 理 解 Map 接 口 的 特 点 4. 熟 练 掌 握 Collection 接 口 的 方 法, 重 点 是 迭 代 方 法 5. 熟 练 掌 握 Map 接 口 中 的 方 法, 重 点 是 迭 代 方 法 6. 查 看 JDK API 文 档 中 和 集 合 相 关 的 API 7. 完 成 课 后 作 业 题, 通 过 老 师 的 讲 解, 理 解 ColDB 的 作 用 和 原 理 ( 讲 过 作 业 题 后 ) 9.9 练 习 1. 写 一 个 方 法 reverselist, 该 方 法 接 收 一 个 List 参 数, 然 后 把 该 List 倒 序 排 列 2. 综 合 设 计 题 : 定 义 一 个 类 ListDB, 类 里 面 有 一 个 属 性 list, 类 型 是 集 合 类 型 List, 实 现 下 列 方 法 : 可 以 向 list 里 面 添 加 数 据 修 改 数 据 查 询 数 据 删 除 数 据 也 就 是 把 这 个 list 当 作 一 个 数 据 存 储 的 容 器, 对 其 实 现 数 据 的 增 删 改 查 的 方 法 注 意 这 些 方 法 是 否 需 要 传 入 参 数, 是 否 应 该 有 返 回 类 型 3. 综 合 设 计 题 : 已 知 有 十 六 支 男 子 足 球 队 参 加 2008 北 京 奥 运 会 写 一 个 程 序, 把 这 16 只 球 队 随 机 分 为 4 个 组 2008 北 京 奥 运 会 男 足 参 赛 国 家 : 科 特 迪 瓦, 阿 根 廷, 澳 大 利 亚, 塞 尔 维 亚, 荷 兰, 尼 日 利 亚 日 本, 美 国, 中 国, 新 西 兰, 巴 西, 比 利 时, 韩 国, 喀 麦 隆, 洪 都 拉 斯, 意 大 利 第 226 页

227 10 图 形 用 户 接 口 AWT 10.1 GUI 的 基 本 概 念 Component AWT 提 供 用 于 所 有 Java applets 及 应 用 程 序 中 的 基 本 GUI 组 件, 还 为 应 用 程 序 提 供 与 机 器 的 界 面 这 将 保 证 一 台 计 算 机 上 出 现 的 东 西 与 另 一 台 上 的 相 一 致 在 学 AWT 之 前, 简 单 回 顾 一 下 对 象 层 次 记 住, 超 类 是 可 以 扩 展 的, 它 们 的 属 性 是 可 继 承 的 而 且, 类 可 以 被 抽 象 化, 这 就 是 说, 它 们 是 可 被 分 成 子 类 的 模 板, 子 类 用 于 类 的 具 体 实 现 显 示 在 屏 幕 上 的 每 个 GUI 组 件 都 是 抽 象 类 组 件 的 子 类 也 就 是 说, 每 个 从 组 件 类 扩 展 来 的 图 形 对 象 都 与 允 许 它 们 运 行 的 大 量 方 法 和 实 例 变 量 共 享 Container Container 是 Component 的 一 个 抽 象 子 类, 它 允 许 其 它 的 组 件 被 嵌 套 在 里 面 这 些 组 件 也 可 以 是 允 许 其 它 组 件 被 嵌 套 在 里 面 的 容 器, 于 是 就 创 建 了 一 个 完 整 的 层 次 结 构 在 屏 幕 上 布 置 GUI 组 件, 容 器 是 很 有 用 的 Panel 是 Container 的 最 简 单 的 类 Container 的 另 一 个 子 类 是 Window Window 是 Java.awt.Window 的 对 象 Window 是 显 示 屏 上 独 立 的 本 机 窗 口, 它 独 立 于 其 它 容 器 Window 有 两 种 形 式 :Frame( 框 架 ) 和 Dialog( 对 话 框 ) Frame 和 Dialog 是 Window 的 子 类 Frame 是 一 个 带 有 标 题 和 缩 放 角 的 窗 口 对 话 没 有 菜 单 条 尽 管 它 能 移 动, 但 它 不 能 缩 放 Panel 是 Java.awt.Panel 的 对 象 Panel 包 含 在 另 一 个 容 器 中, 或 是 在 Web 浏 览 器 的 窗 口 中 Panel 确 定 一 个 四 边 形, 其 它 组 件 可 以 放 入 其 中 Panel 必 须 放 在 Window 之 中 ( 或 Window 的 子 类 中 ) 以 便 能 显 示 出 来 本 的 容 器 不 但 能 容 纳 组 件, 还 能 容 纳 其 它 容 器, 这 一 事 实 对 于 建 立 复 杂 的 布 局 是 关 键 的, 也 是 基 组 件 定 位 容 器 里 的 组 件 的 位 置 是 由 布 局 管 理 器 决 定 的 容 器 对 布 局 管 理 器 的 特 定 实 例 保 持 一 个 引 用 当 容 器 需 要 定 位 一 个 组 件 时, 它 将 调 用 布 局 管 理 器 来 做 当 决 定 一 个 组 件 的 大 小 时, 同 样 如 此 第 227 页

228 布 局 管 理 器 完 全 控 制 容 器 内 的 所 有 组 件 它 负 责 计 算 并 定 义 上 下 文 中 对 象 在 实 际 屏 幕 中 所 需 的 大 小 10.2 容 器 的 基 本 使 用 Frame 的 使 用 Frame 是 Window 的 一 个 子 类 它 是 带 有 标 题 和 缩 放 角 的 窗 口 它 继 承 于 Java.awt.Container, 因 此, 可 以 用 add() 方 式 来 给 框 架 添 加 组 件 框 架 的 缺 省 布 局 管 理 器 就 是 Border Layout 它 可 以 用 setlayout() 方 式 来 改 变 框 架 类 中 的 构 造 程 序 Frame(String) 用 由 String 规 定 的 标 题 来 创 建 一 个 新 的 不 可 见 的 框 架 对 象 当 它 还 处 于 不 可 见 状 态 时, 将 所 有 组 件 添 加 到 框 架 中 import java.awt.*; public class MyFrame extends Frame { public MyFrame(String str) { super(str); public static void main(string args[]) { MyFrame fr = new MyFrame(" 我 的 第 一 个 Frame"); // 设 置 大 小 fr.setsize(500, 500); // 设 置 背 景 颜 色 fr.setbackground(color.blue); // 设 置 框 架 可 见 fr.setvisible(true); 上 述 程 序 创 建 了 下 述 框 架, 它 有 一 个 具 体 的 标 题 大 小 及 背 景 颜 色 第 228 页

229 在 框 架 显 示 在 屏 幕 上 之 前, 必 须 做 成 可 见 的 ( 通 过 调 用 程 序 setvisible(true)), 而 且 其 大 小 是 确 定 的 ( 通 过 调 用 程 序 setsize() 或 pack()) Panel 的 使 用 像 Frame 一 样,Panel 提 供 空 间 来 连 接 任 何 GUI 组 件, 包 括 其 它 面 板 每 个 面 板 都 可 以 有 它 自 己 的 布 管 理 程 序 一 旦 一 个 面 板 对 象 被 创 建, 为 了 能 看 得 见, 它 必 须 添 加 到 窗 口 或 框 架 对 象 上 用 Container 类 中 的 add() 方 式 可 以 做 到 这 一 点 下 面 的 程 序 创 建 了 一 个 小 的 黄 色 面 板, 并 将 它 加 到 一 个 框 架 对 象 上 : import java.awt.*; public class FrameWithPanel extends Frame { // Constructor public FrameWithPanel(String str) { super(str); public static void main(string args[]) { FrameWithPanel fr = new FrameWithPanel(" 我 的 第 一 个 Frame"); Panel pan = new Panel(); fr.setsize(500, 500); fr.setbackground(color.red); 第 229 页

230 fr.setlayout(null); // override default layout mgr pan.setsize(300, 300); pan.setbackground(color.blue); pan.setlayout(null); // override default layout mgr fr.add(pan); fr.setvisible(true); 10.3 AWT 组 件 的 使 用 AWT 组 件 提 供 了 控 制 界 面 外 观 的 机 制, 包 括 用 于 文 本 显 示 的 颜 色 和 字 体 此 外,AWT 还 支 持 打 印 这 个 功 能 是 在 JDK1.1 之 后 中 引 入 的 按 钮 (Button) 你 已 经 比 较 熟 悉 Button 组 件 了 这 个 组 件 提 供 了 按 下 并 动 作 的 基 本 用 户 界 面 可 以 构 造 一 个 带 文 标 签 的 按 钮, 用 来 告 诉 用 户 它 的 作 用 第 230 页

231 Button b=new Button(" 按 钮 "); b.setsize(100,50); b.setlocation(100,100); pan.add(b); 复 选 框 (Checkbox) Checkbox 组 件 提 供 一 种 简 单 的 开 / 关 输 入 设 备, 它 旁 边 有 一 个 文 本 标 签 Checkbox one=new Checkbox("one",true); Checkbox two =new Checkbox("two",false); Checkbox three =new Checkbox("three",false); one.setsize(50,50); two.setsize(50,50); three.setsize(50,50); one.setlocation(50,50); two.setlocation(100,50); three.setlocation(150,50); pan.add(one); pan.add(two); pan.add(three); 第 231 页

232 复 选 框 组 - 单 选 框 (Checkbox group-radio Button) 复 选 框 组 提 供 了 将 多 个 复 选 框 作 为 互 斥 的 一 个 集 合 的 方 法, 因 此 在 任 何 时 刻, 这 个 集 合 中 只 有 一 个 复 选 框 的 值 是 true 值 为 true 的 复 选 框 就 是 当 前 被 选 中 的 复 选 框 你 可 以 使 用 带 有 一 个 额 外 的 CheckboxGroup 参 数 的 构 造 函 数 来 创 建 一 组 中 的 每 个 复 选 框 正 是 这 个 CheckBoxGroup 对 象 将 各 个 复 选 框 连 接 成 一 组 如 果 你 这 么 做 的 话, 那 么 复 选 框 的 外 观 会 发 生 改 变, 而 且 所 有 和 一 个 复 选 框 组 相 关 联 的 复 选 框 将 表 现 出 单 选 框 的 行 为 CheckboxGroup cbg=new CheckboxGroup(); Checkbox one=new Checkbox("one",true,cbg); Checkbox two =new Checkbox("two",false,cbg); Checkbox three =new Checkbox("three",false,cbg); one.setsize(50,50); two.setsize(50,50); three.setsize(50,50); one.setlocation(50,50); two.setlocation(100,50); three.setlocation(150,50); pan.add(one); pan.add(two); pan.add(three); 第 232 页

233 下 拉 列 表 (Choice) 下 拉 列 表 组 件 提 供 了 一 个 简 单 的 从 列 表 中 选 取 一 个 类 型 的 输 入 例 如 : Choice c=new Choice(); c.add("first"); c.add("second"); c.add("third"); c.setsize(100,100); c.setlocation(50,50); pan.add(c); 点 击 下 拉 列 表 组 件 时, 它 会 显 示 一 个 列 表, 列 表 中 包 含 了 所 有 加 入 其 中 的 条 目 注 意 所 加 入 的 条 目 是 String 对 象 第 233 页

234 标 签 (Label) 一 个 标 签 对 象 显 示 一 行 静 态 文 本 程 序 可 以 改 变 文 本, 但 用 户 不 能 改 变 标 签 没 有 任 何 特 殊 的 边 框 和 装 饰 Label lbl=new Label("HelloWorld"); lbl.setsize(100,50); lbl.setlocation(50,50); pa.add(lbl); 标 签 通 常 不 处 理 事 件, 但 也 可 以 按 照 和 画 布 相 同 的 方 式 来 处 理 事 件 也 就 是 说, 只 有 调 用 了 requestfocus() 方 法 后, 才 能 可 靠 地 检 取 击 键 事 件 文 本 域 (Textfield) 文 本 域 是 一 个 单 行 的 文 本 输 入 设 备 例 如 : TextField tf=new TextField(); tf.setsize(300,30); tf.setlocation(50,50); pan.add(tf); 第 234 页

235 文 本 区 (TextArea) 文 本 区 是 一 个 多 行 多 列 的 文 本 输 入 设 备 文 本 区 将 显 示 水 平 和 垂 直 的 滚 动 条 下 面 这 个 范 例 创 建 了 一 个 文 本 区, 最 初 它 含 有 Hello! TextArea t = new TextArea("Hello!"); t.setlocation(100, 100); t.setsize(300, 100); add.add(t); 列 表 (list) 一 个 列 表 将 各 个 文 本 选 项 显 示 在 一 个 区 域 中, 这 样 就 可 以 在 同 时 看 到 若 干 个 条 目 列 表 可 以 滚 动, 并 支 持 单 选 和 多 选 两 种 模 式 例 如 : List lst=new List(); lst.add(" 篮 球 "); lst.add(" 足 球 "); lst.add(" 排 球 "); lst.setsize(50,60); lst.setlocation(50,50); lst.setmultiplemode(true); pa.add(lst); 第 235 页

236 10.4 菜 单 的 实 现 菜 单 与 其 他 组 件 有 一 个 重 要 的 不 同 : 你 不 能 将 菜 单 添 加 到 一 般 的 容 器 中, 而 且 不 能 使 用 布 局 管 理 器 对 它 们 进 行 布 局 你 只 能 将 菜 单 加 到 一 个 菜 单 容 器 中 然 而, 你 可 以 将 一 个 Jmenuswing 组 件 加 到 一 个 Jcontainer 中 你 可 以 通 过 使 用 setmenubar() 方 法 将 菜 单 放 到 一 个 框 架 中, 从 而 启 动 一 个 菜 单 树 从 那 个 时 刻 之 后, 你 可 以 将 菜 单 加 到 菜 单 条 中, 并 将 菜 单 或 菜 单 项 加 到 菜 单 中 弹 出 式 菜 单 是 一 个 例 外, 因 为 它 们 可 以 以 浮 动 窗 口 形 式 出 现, 因 此 不 需 要 布 局 帮 助 菜 单 菜 单 条 的 一 个 特 性 是 你 可 以 将 一 个 菜 单 指 定 为 帮 助 菜 单 这 可 以 用 sethelpmenu(menu) 来 做 到 要 作 为 帮 助 菜 单 的 菜 单 必 须 加 入 到 菜 单 条 中 ; 然 后 它 就 会 以 和 本 地 平 台 的 帮 助 菜 单 同 样 的 方 式 被 处 理 对 于 X/Motif 类 型 的 系 统, 这 涉 及 将 菜 单 条 放 置 在 菜 单 条 的 最 右 边 菜 单 条 (MenuBar) 一 个 菜 单 条 组 件 是 一 个 水 平 菜 单 它 只 能 加 入 到 一 个 框 架 中, 并 成 为 所 有 菜 单 树 的 根 在 一 个 时 刻, 一 个 框 架 可 以 显 示 一 个 菜 单 条 然 而, 你 可 以 根 据 程 序 的 状 态 修 改 菜 单 条, 这 样 在 不 同 的 时 刻 就 可 以 显 示 不 同 的 菜 单 例 如 : MenuBar mb = new MenuBar(); frame.setmenubar(mb); 没 有 菜 单 的 菜 单 条 是 看 不 到 的, 所 以 大 家 在 Frame 中 看 不 到 菜 单 条 的 菜 单 组 件 如 : 菜 单 组 件 提 供 了 一 个 基 本 的 下 拉 式 菜 单 它 可 以 加 入 到 一 个 菜 单 条 或 者 另 一 个 菜 单 中 例 MenuBar mb = new MenuBar(); Menu m1 = new Menu("File"); 第 236 页

237 Menu m2 = new Menu("Edit"); Menu m3 = new Menu("Help"); mb.add(m1); mb.add(m2); mb.sethelpmenu(m3); frame.setmenubar(mb); 这 里 显 示 的 菜 单 是 空 的, 这 正 是 File 菜 单 的 外 观 菜 单 项 (MenuItem) 例 如 : 菜 单 项 组 件 是 菜 单 树 的 文 本 叶 结 点 它 们 通 常 被 加 入 到 菜 单 中, 以 构 成 一 个 完 整 的 菜 单 MenuItem mi1 = new MenuItem("New"); MenuItem mi2 = new MenuItem("Load"); MenuItem mi3 = new MenuItem("Save"); MenuItem mi4 = new MenuItem("Quit"); m1.add(mi1); m1.add(mi2); m1.addseparator(); m1.add(mi3); 复 选 菜 单 项 (CheckboxMenuItem) 复 选 菜 单 项 是 一 个 可 复 选 的 菜 单 项, 所 以 你 可 以 在 菜 单 上 有 选 项 ( 开 或 关 ) 例 如 : 第 237 页

238 MenuItem mi1 = new MenuItem("Save"); CheckboxMenuItem mi2 =new CheckboxMenuItem("Persistent"); m1.add(mi1); m1.add(mi2); 弹 出 式 菜 单 (PopupMenu) 弹 出 式 菜 单 提 供 了 一 种 独 立 的 菜 单, 它 可 以 在 任 何 组 件 上 显 示 你 可 以 将 菜 单 条 目 和 菜 单 加 入 到 弹 出 式 菜 单 中 去 例 如 : PopupMenu p = new PopupMenu("Popup"); MenuItem s = new MenuItem("Save"); MenuItem l = new MenuItem("Load"); p.add(s); p.add(l); frame.add(p); // 显 示 弹 出 式 菜 单 p.show(fr, 100, 70); 注 - 弹 出 式 菜 单 必 须 加 入 到 一 个 父 组 件 中 这 与 将 组 件 加 入 到 容 器 中 是 不 同 的 在 上 面 这 个 范 例 中, 弹 出 式 菜 单 被 加 入 到 周 围 的 框 架 中 10.5 控 制 外 观 你 可 以 控 制 在 AWT 组 件 中 所 显 示 的 文 本 的 前 景 背 景 颜 色 背 景 颜 色 和 字 体 第 238 页

239 10.6 布 局 管 理 器 和 布 局 FlowLayout( 流 式 布 局 ) 使 用 FlowLayout 布 局 方 式 的 容 器 中 组 件 按 照 加 入 的 先 后 顺 序 按 照 设 置 的 对 齐 方 式 ( 居 中 左 对 齐 右 对 齐 ) 从 左 向 右 排 列, 一 行 排 满 ( 即 组 件 超 过 容 器 宽 度 后 ) 到 下 一 行 开 始 继 续 排 列 流 式 布 局 特 征 如 下 : 组 件 按 照 设 置 的 对 齐 方 式 进 行 排 列 不 管 对 齐 方 式 如 何, 组 件 均 按 照 从 左 到 右 的 方 式 进 行 排 列, 一 行 排 满, 转 到 下 一 行 ( 比 如 按 照 右 对 齐 排 列, 第 一 个 组 件 在 第 一 行 最 右 边, 添 加 第 二 个 组 件 时, 第 一 个 组 件 向 左 平 移, 第 二 个 组 件 变 成 该 行 最 右 边 的 组 件, 这 就 是 从 左 向 右 方 式 进 行 排 列 ) import java.awt.button; import java.awt.flowlayout; import java.awt.font; import java.awt.frame; public class FlowLayoutDemo extends Frame { public FlowLayoutDemo() { // 设 置 窗 体 为 流 式 布 局, 无 参 数 默 认 为 居 中 对 齐 setlayout(new FlowLayout()); // 设 置 窗 体 中 显 示 的 字 体 样 式 setfont(new Font("Helvetica", Font.PLAIN, 14)); // 将 按 钮 添 加 到 窗 体 中 this.add(new Button("Button 1")); this.add(new Button("Button 2")); this.add(new Button("Button3")); this.add(new Button("Button 4")); public static void main(string args[]) { FlowLayoutDemo frame = new FlowLayoutDemo(); frame.settitle(" 流 式 布 局 "); // 该 代 码 依 据 放 置 的 组 件 设 定 窗 口 的 大 小 使 之 正 好 能 容 纳 你 放 置 的 所 有 组 件 frame.pack(); frame.setvisible(true); frame.setlocationrelativeto(null); // 让 窗 体 居 中 显 示 第 239 页

240 原 始 界 面 : 拉 伸 原 始 界 面 : 拉 窄 原 始 界 面 : BorderLayout( 边 框 布 局 ) Border 布 局 管 理 器 为 在 一 个 Panel 或 Window 中 放 置 组 件 提 供 一 个 更 复 杂 的 方 案 Border 布 局 管 理 器 包 括 五 个 明 显 的 区 域 : 东 南 西 北 中 北 占 据 面 板 的 上 方, 东 占 据 面 板 的 右 侧, 等 等 中 间 区 域 是 在 东 南 西 北 都 填 满 后 剩 下 的 区 域 当 窗 口 垂 直 延 伸 时, 东 西 中 区 域 也 延 伸 ; 而 当 窗 口 水 平 延 伸 时, 东 西 中 区 域 也 延 伸 Border 布 局 管 理 器 是 用 于 Dialog 和 Frame 的 缺 省 布 局 管 理 器 第 240 页

241 当 窗 口 缩 放 时, 按 钮 相 应 的 位 置 不 变 化, 但 其 大 小 改 变 import java.awt.borderlayout; import java.awt.button; import java.awt.frame; public class BorderLayoutDemo extends Frame{ public BorderLayoutDemo(){ Button N=new Button(" 北 "); Button S=new Button(" 南 "); Button W=new Button(" 西 "); Button E=new Button(" 东 "); Button C=new Button(" 中 "); this.add(n,borderlayout.north); this.add(s,borderlayout.south); this.add(w,borderlayout.west); this.add(e,borderlayout.east); this.add(c,borderlayout.center); public static void main(string[] args){ BorderLayoutDemo frame = new BorderLayoutDemo(); frame.settitle(" 边 框 布 局 "); // 该 代 码 依 据 放 置 的 组 件 设 定 窗 口 的 大 小 使 之 正 好 能 容 纳 你 放 置 的 所 有 组 件 frame.pack(); frame.setvisible(true); frame.setlocationrelativeto(null); // 让 窗 体 居 中 显 示 GridLayout( 网 格 布 局 ) Grid 布 局 管 理 器 为 放 置 组 件 提 供 了 灵 活 性 用 许 多 行 和 栏 来 创 建 管 理 程 序 然 后 组 件 就 填 充 到 由 管 理 程 序 规 定 的 单 元 中 比 如, 由 语 句 new GridLayout(3,2) 创 建 的 有 三 行 两 栏 的 第 241 页

242 Grid 布 局 能 产 生 如 下 六 个 单 元 : 变 因 为 有 Border 布 局 管 理 器, 组 件 相 应 的 位 置 不 随 区 域 的 缩 放 而 改 变 只 是 组 件 的 大 小 改 Grid 布 局 管 理 器 总 是 忽 略 组 件 的 最 佳 大 小 所 有 单 元 的 宽 度 是 相 同 的, 是 根 据 单 元 数 对 可 用 宽 度 进 行 平 分 而 定 的 同 样 地, 所 有 单 元 的 高 度 是 相 同 的, 是 根 据 行 数 对 可 用 高 度 进 行 平 分 而 定 的 将 组 件 添 加 到 网 格 中 的 命 令 决 定 它 们 占 有 的 单 元 单 元 的 行 数 是 从 左 到 右 填 充, 就 象 文 本 一 样, 而 页 是 从 上 到 下 由 行 填 充 import java.awt.borderlayout; import java.awt.button; import java.awt.frame; import java.awt.gridlayout; import java.awt.panel; import java.awt.textfield; public class GridLayoutDemo extends Frame { public GridLayoutDemo() { // 创 建 第 一 个 Panel, 显 示 输 入 框 Panel p1 = new Panel(); p1.add(new TextField(30)); this.add(p1,borderlayout.north); // 创 建 第 一 个 Panel, 显 示 数 字 和 操 作 符 的 按 钮 Panel p2 = new Panel(); p2.setlayout(new GridLayout(3, 5, 4, 4)); String[] name = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "+", "-", "*", "/", "." ; for (int i = 0; i < name.length; i++) { p2.add(new Button(name[i])); this.add(p2); public static void main(string[] args) { GridLayoutDemo frame = new GridLayoutDemo(); 第 242 页

243 frame.settitle(" 网 格 布 局 "); // 该 代 码 依 据 放 置 的 组 件 设 定 窗 口 的 大 小 使 之 正 好 能 容 纳 你 放 置 的 所 有 组 件 frame.pack(); frame.setvisible(true); frame.setlocationrelativeto(null); // 让 窗 体 居 中 显 示 CardLayout( 卡 片 布 局 ) Card 布 局 管 理 器 能 将 界 面 看 作 一 系 列 的 卡, 其 中 的 一 个 在 任 何 时 候 都 可 见 用 add() 方 法 来 将 卡 添 加 到 Card 布 局 中 Card 布 局 管 理 器 的 show() 方 法 应 请 求 转 换 到 一 个 新 卡 中 下 例 就 是 一 个 带 有 5 张 卡 的 框 架 import java.awt.*; import java.awt.event.actionevent; import java.awt.event.actionlistener; public class CardLayoutDemo { Frame f; Panel p1; 第 243 页

244 Panel p2; String[] name = { "1", "2", "3", "4", "5" ; CardLayout c; public CardLayoutDemo(){ f = new Frame(" 卡 片 布 局 "); p1 = new Panel(); p2 = new Panel(); c = new CardLayout(); p1.setlayout(c); for (int i = 0; i < name.length; i++){ p1.add(name[i], new Button(name[i])); // 控 制 显 示 上 一 张 的 按 钮 Button previous = new Button(" 上 一 张 "); previous.addactionlistener(new ActionListener(){ public void actionperformed(actionevent e){ c.previous(p1); ); // 控 制 显 示 下 一 张 的 按 钮 Button next = new Button(" 下 一 张 "); next.addactionlistener(new ActionListener(){ public void actionperformed(actionevent e){ c.next(p1); ); // 控 制 显 示 第 一 张 的 按 钮 Button first = new Button(" 第 一 张 "); first.addactionlistener(new ActionListener(){ public void actionperformed(actionevent e){ c.first(p1); ); // 控 制 显 示 最 后 一 张 的 按 钮 Button last = new Button(" 最 后 一 张 "); last.addactionlistener(new ActionListener(){ public void actionperformed(actionevent e){ c.last(p1); ); // 根 据 card 名 显 示 的 按 钮 第 244 页

245 Button third = new Button(" 第 三 张 "); third.addactionlistener(new ActionListener(){ public void actionperformed(actionevent e) { c.show(p1, "3"); ); p2.add(previous); p2.add(next); p2.add(first); p2.add(last); p2.add(third); f.add(p1);// 默 认 添 加 到 中 间 f.add(p2, BorderLayout.SOUTH); f.pack(); f.setvisible(true); public static void main(string[] args){ new CardLayoutDemo(); GridBag 布 局 管 理 器 除 了 Flow Border Grid 和 Card 布 局 管 理 器 外, 核 心 Java.awt 也 提 供 GridBag 布 局 管 理 器 GridBag 布 局 管 理 器 在 网 格 的 基 础 上 提 供 复 杂 的 布 局, 但 它 允 许 单 个 组 件 在 一 个 单 元 中 而 不 是 填 满 整 个 单 元 那 样 地 占 用 它 们 的 最 佳 大 小 网 格 包 布 局 管 理 器 也 允 许 单 个 组 件 扩 展 成 不 止 一 个 单 元 第 245 页

246 11 I/O 流 11.1 File 类 创 建 File 对 象 File 类 的 对 象 主 要 用 来 获 取 文 件 本 身 的 一 些 信 息, 例 如 文 件 所 在 的 目 录, 文 件 的 长 度, 文 件 读 写 权 限 等, 不 涉 及 对 文 件 的 读 写 操 作 创 建 一 个 File 对 象 的 构 造 方 法 有 3 个 public File(String pathname) public File(String parentpath, String filename) public File(File parentfile, String filename) 其 中,pathname 和 filename 是 文 件 名 字,parentPath 是 文 件 的 路 径,parentFile 是 指 定 的 一 个 目 录 文 件 File 类 的 方 法 public boolean canwrite() 判 断 文 件 是 否 可 被 写 入 // 创 建 一 个 文 件 对 象,( 在 硬 盘 中 没 有 javakc.txt 文 件 ) File f=new File("d:/javakc.txt"); // 判 断 此 文 件 是 否 可 写 boolean flag=f.canwrite(); // 输 出 结 果 :false System.out.println(flag); public boolean exists() 判 断 文 件 是 否 存 在 // 创 建 一 个 文 件 对 象 File f=new File("d:/javakc.txt");// 文 件 在 硬 盘 中 存 在 File f2=new File("d:/kc/javakc.txt");// 文 件 在 硬 盘 中 不 存 在 // 输 出 文 件 是 否 存 在 System.out.println(f.exists());//true System.out.println(f2.exists());//false 第 246 页

247 public boolean createnewfile() 当 且 仅 当 不 存 在 具 有 此 抽 象 路 径 名 指 定 名 称 的 文 件 时, 不 可 分 地 创 建 一 个 新 的 空 文 件 // 创 建 一 个 文 件 对 象,( 在 硬 盘 中 没 有 javakc.txt 文 件 ) File f=new File("d:/javakc.txt"); // 创 建 文 件 boolean flag=f.createnewfile(); // 第 二 次 创 建 文 件 boolean flag2=f.createnewfile(); // 输 出 结 果 System.out.println(flag);//true System.out.println(flag2);//false public String getname() 获 取 文 件 的 名 字 // 创 建 一 个 文 件 对 象 File f=new File("d:/javakc.txt"); // 输 出 文 件 的 名 称 System.out.println(f.getName());//javakc.txt public long length() 获 取 文 件 的 长 度, 单 位 是 字 节 // 创 建 一 个 文 件 对 象 File f=new File("d:/javakc.txt");// 文 件 在 硬 盘 中 存 在 且 文 件 不 为 空 File f2=new File("d:/javakc2.txt");// 文 件 在 硬 盘 中 存 在 且 文 件 为 空 File f3=new File("d:/kc/javakc.txt");// 文 件 在 硬 盘 中 不 存 在 // 输 出 文 件 的 长 度 System.out.println(f.length());//6 System.out.println(f2.length());//0 System.out.println(f3.length());//0 public boolean equals(object obj) 测 试 此 抽 象 路 径 名 与 给 定 对 象 是 否 相 等 // 创 建 文 件 对 象 File f=new File("d:/javakc.txt"); File f2=new File("d:/javakc.txt"); // 输 出 两 个 文 件 是 否 相 等 System.out.println(f.equals(f2));//true // 使 用 相 对 路 径 创 建 文 件 对 象 File f3=new File("javakc.txt"); // 使 用 绝 对 路 径 创 建 文 件 对 象 File f4=new File("D:/work/javakc38/JseTest/javakc.txt"); // 输 出 两 个 文 件 是 否 相 等 System.out.println(f3.equals(f4));//false 第 247 页

248 public String getabsolutefile() 获 取 文 件 的 绝 对 路 径 // 使 用 相 对 路 径 创 建 文 件 对 象 File f3=new File("javakc.txt"); // 使 用 绝 对 路 径 创 建 文 件 对 象 File f4=new File("D:/work/javakc38/JseTest/javakc.txt"); // 输 出 两 个 文 件 是 否 相 等 System.out.println(f3.equals(f4));//false // 将 相 对 路 径 转 换 成 绝 对 路 径 File f5=f3.getabsolutefile(); System.out.println(f4.equals(f5));//true public boolean isfile() 测 试 此 抽 象 路 径 名 表 示 的 文 件 是 否 是 一 个 标 准 文 件 public boolean isdirectory() 测 试 此 抽 象 路 径 名 表 示 的 文 件 是 否 是 一 个 目 录 // 创 建 文 件 对 象 File f=new File("d:/javakc.txt"); File f2=new File("d:/kc"); // 测 试 此 抽 象 路 径 名 表 示 的 文 件 是 否 是 一 个 标 准 文 件 System.out.println(f.isFile());//true System.out.println(f2.isFile());//false // 测 试 此 抽 象 路 径 名 表 示 的 文 件 是 否 是 一 个 目 录 System.out.println(f.isDirectory());//false System.out.println(f2.isDirectory());//true public File[] listfiles() 返 回 一 个 抽 象 路 径 名 数 组, 这 些 路 径 名 表 示 此 抽 象 路 径 名 表 示 的 目 录 中 的 文 件 // 创 建 文 件 对 象 File f=new File("D:/work/javakc38/JseTest"); // 取 得 目 录 中 的 所 有 文 件 File[] fs=f.listfiles(); for(file child:fs){ System.out.println(child); 输 出 结 果 : D:\work\javakc38\JseTest\.classpath D:\work\javakc38\JseTest\.project D:\work\javakc38\JseTest\.settings D:\work\javakc38\JseTest\bin D:\work\javakc38\JseTest\javakc.txt D:\work\javakc38\JseTest\src 第 248 页

249 public String getparent() 获 取 文 件 的 父 目 录 // 创 建 文 件 对 象 File f=new File("javakc.txt"); // 根 据 相 对 路 径 转 换 成 绝 对 路 径 File f2=f.getabsolutefile();//d:\work\javakc38\jsetest\javakc.txt // 得 到 f2 的 父 目 录 File parent=f2.getparentfile(); System.out.println(parent);// D:\work\javakc38\JseTest public File[] listfiles(filefilter filter) 返 回 抽 象 路 径 名 数 组, 这 些 路 径 名 表 示 此 抽 象 路 径 名 表 示 的 目 录 中 满 足 指 定 过 滤 器 的 文 件 和 目 录 File f=new File("D:/work/javakc38/JseTest"); // 通 过 文 件 过 滤 器 取 得 目 录 中 的 所 有 标 准 文 件 File[] fs=f.listfiles(new FileFilter(){ // 文 件 过 滤 器 中 的 过 滤 方 法 public boolean accept(file f) { // 当 此 文 件 为 标 准 文 件 时 返 回 true if(f.isfile()){ return true; return false; ); // 展 示 结 果 for(file child:fs){ System.out.println(child); // 创 建 文 件 对 象 输 出 结 果 ( 只 有 文 件, 没 有 目 录 ): D:\work\javakc38\JseTest\.classpath D:\work\javakc38\JseTest\.project D:\work\javakc38\JseTest\javakc.txt public long getfreespace() 返 回 此 抽 象 路 径 名 指 定 的 分 区 中 未 分 配 的 字 节 数 // 创 建 文 件 对 象 File f=new File("D:/work/javakc38/JseTest"); System.out.println("D 盘 中 未 分 配 的 字 节 数 :"+f.getfreespace()); public boolean mkdir() 创 建 此 抽 象 路 径 名 指 定 的 目 录 // 创 建 文 件 对 象 第 249 页

250 File f=new File("D:/work/javakc40"); // 创 建 目 录 f.mkdir(); 目 录 public boolean mkdirs() 创 建 此 抽 象 路 径 名 指 定 的 目 录, 包 括 所 有 必 需 但 不 存 在 的 父 // 创 建 文 件 对 象 File f=new File("D:/work/javakc41/kc"); // 创 建 目 录 f.mkdirs(); public boolean renameto(file dest) 重 新 命 名 此 抽 象 路 径 名 表 示 的 文 件 // 创 建 文 件 对 象 File f=new File("D:/javakc.txt"); File f2=new File("D:/javakc39.txt"); // 修 改 文 件 名 称 f.renameto(f2); 第 250 页

251 11.2 流 的 基 本 知 识 流 是 字 节 从 源 到 目 的 的 轨 迹, 次 序 是 有 意 义 的 两 种 基 本 的 流 是 : 输 入 流 和 输 出 流 你 可 以 从 输 入 流 读, 但 你 不 能 对 它 写 要 从 输 入 流 读 取 字 节, 必 须 有 一 个 与 这 个 流 相 关 联 的 字 符 源 绍 在 java.io 包 中 定 义 了 一 些 流 类 下 图 表 明 了 包 中 的 类 层 次 一 些 更 公 共 的 类 将 在 后 面 介 11.3 FileInputStream 类 如 果 需 要 从 本 地 硬 盘 读 取 文 件, 可 以 使 用 FileInputStream 类, 该 类 是 从 InputStream 中 派 生 出 来 的 简 单 输 入 类 该 类 的 所 有 方 法 都 是 从 InputStream 类 继 承 来 的 为 了 创 建 FileInputStream 类 的 对 象, 可 以 调 用 下 面 两 个 构 造 方 法 : FileInputStream(String name) FileInputStream(File file) 第 一 个 构 造 器 使 用 给 定 的 文 件 名 name 创 建 一 个 FileInputStream 对 象, 第 二 个 构 造 器 使 用 File 对 象 创 建 FileInputStream 对 象 第 251 页

252 创 建 文 件 输 入 流 例 如 读 取 一 个 名 为 a.txt 的 文 件, 建 立 一 个 文 件 输 入 流 对 象, 如 下 所 示 : FileInputStream fis=new FileInputStream("a.txt"); 或 者 使 用 File 对 象 : File f=new File("a.txt"); FileInputStream fis=new FileInputStream(f); 处 理 IO 异 常 当 使 用 文 件 输 入 流 构 造 器 建 立 通 往 文 件 的 输 入 流 时, 可 能 会 出 现 异 常 例 如, 试 图 要 打 开 的 文 件 可 能 不 存 在, 就 会 出 现 IO 异 常 程 序 必 须 使 用 一 个 try-catch 块 检 测 并 处 理 这 个 异 常 示 例 如 下 : FileInputStream fis=null; try { fis=new FileInputStream("a.txt"); catch (FileNotFoundException e) { // 文 件 不 存 在 异 常 System.out.println("File read error:"+e); 由 于 IO 操 作 对 于 错 误 特 别 敏 感, 所 以 许 多 其 他 的 流 类 构 造 器 和 方 法 也 抛 出 IO 异 常, 你 都 可 以 按 照 上 述 程 序 段 的 方 式 捕 获 处 理 这 些 异 常 从 输 入 流 中 读 取 字 节 输 入 流 的 唯 一 目 的 是 提 供 通 往 数 据 的 通 道, 程 序 可 以 通 过 这 个 通 道 读 取 数 据 Read 方 法 给 程 序 提 供 一 个 从 输 入 流 中 读 取 数 据 的 基 本 方 法 int read( ) 从 输 入 流 中 读 取 数 据 的 下 一 个 字 节 返 回 0 到 255 范 围 内 的 int 字 节 值 如 果 因 为 已 经 到 达 流 末 尾 而 没 有 可 用 的 字 节, 则 返 回 值 -1 int read(byte[] b) 从 输 入 流 中 读 取 一 定 数 量 的 字 节, 并 将 其 存 储 在 缓 冲 区 数 组 b 中 以 整 数 形 式 返 回 实 际 读 取 的 字 节 数 如 果 遇 到 输 入 流 的 结 尾, 则 返 回 -1 int read(byte[] b,int off, int len ) 这 三 个 方 法 提 供 对 输 入 管 道 数 据 的 存 取 简 单 读 方 法 返 回 一 个 int 值, 它 包 含 从 流 里 读 出 的 一 个 字 节 或 者 -1, 其 中 后 者 表 明 文 件 结 束 其 它 两 种 方 法 将 数 据 读 入 到 字 节 数 组 中, 并 返 回 所 第 252 页

253 读 的 字 节 数 第 三 个 方 法 中 的 两 个 int 参 数 指 定 了 所 要 填 入 的 数 组 的 子 范 围 FileInputStream 流 顺 序 地 读 取 文 件, 只 要 不 关 闭 流, 每 次 调 用 read 方 法 就 顺 序 地 读 取 源 其 余 的 内 容, 直 到 流 的 末 尾 或 流 被 关 闭 关 闭 流 虽 然 Java 在 程 序 结 束 时 自 动 关 闭 所 有 打 开 的 流, 但 是 当 我 们 使 用 完 流 后, 显 式 地 关 闭 任 何 打 开 的 流 仍 是 一 个 良 好 的 习 惯 一 个 被 打 开 的 流 可 能 会 用 尽 系 统 资 源, 这 取 决 于 平 台 和 实 现 如 果 没 有 关 闭 那 些 被 打 开 的 流, 那 么 在 另 一 个 程 序 可 能 无 法 得 到 这 些 资 源 关 闭 输 出 流 的 另 一 个 原 因 是 把 该 缓 冲 区 的 内 容 刷 出, 也 就 是 把 缓 冲 区 的 内 容 写 到 目 的 地 FileInputStream fis = null; try { File f = new File("a.txt"); // 创 建 字 节 流 fis = new FileInputStream(f); // 根 据 文 件 的 大 小, 创 建 相 同 长 度 的 字 节 数 组 byte[] arr = new byte[(int) f.length()]; // 读 取 流 中 的 数 据 到 字 节 数 组 中 fis.read(arr); // 将 读 取 的 数 据 转 换 成 String String msg = new String(arr); System.out.println(msg); catch (IOException e) { e.printstacktrace(); finally { // 判 断 字 节 流 是 否 为 空 if (fis!= null) { try { // 关 闭 字 节 流 fis.close(); catch (IOException e) { e.printstacktrace(); 11.4 FileOutputStream 类 与 FileInputStream 类 相 对 应 的 类 是 FileOutputStream 类 FileOutputStream 提 供 了 基 本 的 文 件 写 入 能 力 FileOutputStream 类 有 两 个 构 造 方 法 : FileOutputStream(String name) 第 253 页

254 FileOutputStream(File file) FileOutputStream 类 有 三 个 基 本 的 write() 方 法 void write(int n) void write(byte b[]) void write(byte b[], int off, int len) 这 些 方 法 写 输 出 流 和 输 入 一 样, 总 是 尝 试 以 实 际 最 大 的 块 进 行 写 操 作 void close() 当 你 完 成 写 操 作 后, 就 关 闭 输 出 流 如 果 你 有 一 个 流 所 组 成 的 栈, 就 关 闭 栈 顶 部 的 流 这 个 关 闭 操 作 会 关 闭 其 余 的 流 void flush() 操 作 有 时 一 个 输 出 流 在 积 累 了 若 干 次 之 后 才 进 行 真 正 的 写 操 作 flush() 方 法 允 许 你 强 制 执 行 写 11.5 对 象 字 节 流 ObjectInputStream 和 ObjectOutputStream ObjectInputStream 类 和 ObjectOutputStream 类 分 别 是 InputStream 类 和 OutputStream 类 的 子 类 ObjectInputStream 类 和 ObjectOutputStream 类 创 建 的 对 象 被 称 为 对 象 输 入 流 和 对 象 输 出 流 对 象 输 出 流 使 用 writeobject(object obj) 方 法 将 一 个 对 象 obj 写 入 到 一 个 文 件, 对 象 输 入 流 使 用 readobject() 读 取 一 个 对 象 到 程 序 中 ObjectInputStream 类 和 ObjectOutputStream 类 的 构 造 方 法 分 别 是 : ObjectInputStream(InputStream in) ObjectOutputStream(OutputStream out) ObjectOutputStream 的 指 向 的 是 一 个 输 出 流 对 象, 因 此 准 备 将 一 个 对 象 写 入 到 文 件 时, 首 先 用 FileOutputStream 创 建 一 个 文 件 输 出 流, 如 下 所 示 : FileOutputStream fos = null; 第 254 页

255 ObjectOutputStream oos=null; try { File f = new File("javakc.txt"); // 创 建 字 节 流 fos = new FileOutputStream(f); // 创 建 对 象 流 oos=new ObjectOutputStream(fos); // 将 日 期 对 象 写 入 到 对 象 流 中 Date d=new Date(); oos.writeobject(d); catch (IOException e) { e.printstacktrace(); finally { // 关 闭 流 if (oos!= null) { try { oos.close(); catch (IOException e) { e.printstacktrace(); 同 样 ObjectInputStream 的 指 向 应 当 是 一 个 输 入 流 对 象, 因 此 当 准 备 从 文 件 中 读 入 一 个 对 象 到 程 序 中 时, 首 先 用 FileInputStream 创 建 一 个 文 件 输 入 流, 如 下 列 代 码 所 以 : FileInputStream fis = null; ObjectInputStream ois=null; try { File f = new File("javakc.txt"); // 创 建 字 节 流 fis = new FileInputStream(f); // 创 建 对 象 流 ois=new ObjectInputStream(fis); // 从 对 象 流 中 读 取 出 日 期 对 象 Object o=ois.readobject(); Date d=(date)o; System.out.println(o); catch (Exception e) { e.printstacktrace(); finally { // 关 闭 流 if (ois!= null) { try { ois.close(); catch (IOException e) { e.printstacktrace(); 第 255 页

256 串 行 化 将 一 个 对 象 存 放 到 某 种 类 型 的 永 久 存 储 器 上 称 为 保 持 如 果 一 个 对 象 可 以 被 存 放 到 磁 盘 或 磁 带 上, 或 者 可 以 发 送 到 另 外 一 台 机 器 并 存 放 到 存 储 器 或 磁 盘 上, 那 么 这 个 对 象 就 被 称 为 可 保 持 的 java.io.serializable 接 口 没 有 任 何 方 法, 它 只 作 为 一 个 标 记 者, 用 来 表 明 实 现 了 这 个 接 口 的 类 可 以 考 虑 串 行 化 类 中 没 有 实 现 Serializable 的 对 象 不 能 保 存 或 恢 复 它 们 的 状 态 当 一 个 对 象 被 串 行 化 时, 只 有 对 象 的 数 据 被 保 存 ; 方 法 和 构 造 函 数 不 属 于 串 行 化 流 如 果 一 个 数 据 变 量 是 一 个 对 象, 那 么 这 个 对 象 的 数 据 成 员 也 会 被 串 行 化 树 或 者 对 象 数 据 的 结 构, 包 括 这 些 子 对 象, 构 成 了 对 象 图 因 为 有 些 对 象 类 所 表 示 的 数 据 在 不 断 地 改 变, 所 以 它 们 不 会 被 串 行 化 ; 例 如, java.io.fileinputstream java.io.fileoutputstream 和 java.lang.thread 等 流 如 果 一 个 可 串 行 化 对 象 包 含 对 某 个 不 可 串 行 化 元 素 的 引 用, 那 么 整 个 串 行 化 操 作 就 会 失 败, 而 且 会 抛 出 一 个 NotSerializableException 如 果 对 象 图 包 含 一 个 不 可 串 行 化 的 引 用, 只 要 这 个 引 用 已 经 用 transient 关 键 字 进 行 了 标 记, 那 么 对 象 仍 然 可 以 被 串 行 化 public class MyClass implements Serializable { public transient Thread mythread; private String customerid; private int total; 11.6 缓 冲 字 节 流 第 256 页

257 java.io.bufferedinputstream 与 java.io.bufferedoutputstream 可 以 为 InputStream OutputStream 类 增 加 缓 冲 区 功 能 构 建 BufferedInputStream 实 例 时, 需 要 给 定 一 个 InputStream 类 型 的 实 例, 实 现 BufferedInputStream 时, 实 际 上 最 后 是 实 现 InputStream 实 例 同 样, 构 建 BufferedOutputStream 时, 也 需 要 给 定 一 个 OutputStream 实 例, 实 现 BufferedOutputStream 时, 实 际 上 最 后 是 实 现 OutputStream 实 例 BufferedInputStream 的 数 据 成 员 buf 是 一 个 位 数 组, 默 认 为 2048 字 节 当 读 取 数 据 来 源 时, 例 如 文 件,BufferedInputStream 会 尽 量 将 buf 填 满 当 使 用 read() 方 法 时, 实 际 上 是 先 读 取 buf 中 的 数 据, 而 不 是 直 接 对 数 据 来 源 作 读 取 当 buf 中 的 数 据 不 足 时, BufferedInputStream 才 会 再 实 现 给 定 的 InputStream 对 象 的 read() 方 法, 从 指 定 的 装 置 中 提 取 数 据 BufferedOutputStream 的 数 据 成 员 buf 也 是 一 个 位 数 组, 默 认 为 512 字 节 当 使 用 write() 方 法 写 入 数 据 时 实 际 上 会 先 将 数 据 写 到 buf 中, 当 buf 已 满 时 才 会 实 现 给 定 的 OutputStream 对 象 的 write() 方 法, 将 buf 数 据 写 到 目 的 地, 而 不 是 每 次 都 对 目 的 地 作 写 入 的 动 作 下 面 示 例 中, 将 javakc.jpg 复 制 成 temp.jpg: byte[] data = new byte[1024]; File srcfile = new File("D:/javakc.jpg"); File desfile = new File("E:/temp.jpg"); BufferedInputStream bis = null; BufferedOutputStream bos = null; try { bis = new BufferedInputStream(new FileInputStream(srcFile)); bos = new BufferedOutputStream(new FileOutputStream(desFile)); System.out.println(" 复 制 文 件 :" + srcfile.length() + " 字 节 "); // 存 储 读 取 文 件 的 长 度 int len=0; while ( len=(bis.read(data))!= -1) { bos.write(data,0,len); // 将 缓 冲 区 中 的 数 据 全 部 写 出 bos.flush(); catch (Exception e) { e.printstacktrace(); finally { // 关 闭 流 try { if (bis!= null) { 第 257 页

258 bis.close(); if (bos!= null) { bos.close(); catch (Exception e) { e.printstacktrace(); System.out.println(" 复 制 完 成 "); 为 了 确 保 缓 冲 区 中 的 数 据 一 定 被 写 出 至 目 的 地, 建 议 最 后 执 行 flush() 将 缓 冲 区 中 的 数 据 全 部 写 出 目 的 流 中 11.7 数 据 字 节 流 DataInputStream 类 和 DataOutputStream 类 创 建 的 对 象 被 称 为 数 据 输 入 流 和 数 据 输 出 流 数 据 流 允 许 程 序 按 照 机 器 无 关 的 风 格 读 取 操 作 数 据, 也 就 是 当 我 们 操 作 一 个 数 据 时, 不 必 关 心 这 个 数 值 应 当 是 多 少 个 字 节 // 写 操 作 FileOutputStream fos = null; DataOutputStream dos = null; try { File f = new File("javakc.txt"); // 创 建 字 节 流 fos = new FileOutputStream(f); dos = new DataOutputStream(fos); // 写 入 数 据 dos.writeint(2013); dos.writeutf("java 快 车,ok"); dos.writefloat(100.0f); catch (IOException e) { e.printstacktrace(); finally { // 关 闭 流 if (dos!= null) { try { dos.close(); catch (IOException e) { e.printstacktrace(); // 读 操 作 FileInputStream fis = null; DataInputStream dis = null; 第 258 页

259 try { File f = new File("javakc.txt"); // 创 建 字 节 流 fis = new FileInputStream(f); dis = new DataInputStream(fis); // 读 出 数 据 int firstint = dis.readint(); String str = dis.readutf(); float secflt = dis.readfloat(); System.out.println(firstInt+","+str+","+secFlt); catch (IOException e) { e.printstacktrace(); finally { // 关 闭 流 if (dis!= null) { try { dis.close(); catch (IOException e) { e.printstacktrace(); 11.8 字 符 流 Reader 和 Writer Java 技 术 使 用 Unicode 来 表 示 字 符 串 和 字 符, 而 且 它 提 供 了 16 位 版 本 的 流, 以 便 用 类 似 的 方 法 来 处 理 字 符 这 些 16 位 版 本 的 流 称 为 读 者 和 作 者 和 流 一 样, 它 们 都 在 java.io 包 中 读 者 和 作 者 中 最 重 要 的 版 本 是 InputStreamReader 和 OutputStreamWriter 这 些 类 用 来 作 为 字 节 流 与 读 者 和 作 者 之 间 的 接 口 当 你 构 造 一 个 InputStreamReader 或 OutputStreamWriter 时, 转 换 规 则 定 义 了 16 位 Unicode 和 其 它 平 台 的 特 定 表 示 之 间 的 转 换 缺 省 情 况 下, 如 果 你 构 造 了 一 个 连 接 到 流 的 读 者 和 作 者, 那 么 转 换 规 则 会 在 使 用 缺 省 平 台 所 定 义 的 字 节 编 码 和 Unicode 之 间 切 换 在 英 语 国 家 中, 所 使 用 的 字 节 编 码 是 :ISO 第 259 页

260 字 符 流 在 进 行 中 文 操 作 时 会 更 加 方 便 和 准 确, 比 如 在 读 取 中 文 文 档 内 容 时, 字 节 流 可 能 会 读 取 到 中 文 的 一 半, 而 字 符 流 则 不 会 出 现 这 样 的 问 题 比 如, 我 们 用 字 节 流 读 取 大 文 件, 需 要 通 过 字 节 数 组, 一 批 一 批 将 数 据 读 取 出 来, 代 码 如 下 FileInputStream fis = null; try { File f = new File("javakc.txt"); // 创 建 字 节 流 fis = new FileInputStream(f); // 创 建 字 节 数 组, 每 次 读 取 5 个 字 节 byte[] arr = new byte[5]; // 读 取 的 字 节 长 度 int length=0; while((length=fis.read(arr))!=-1){ // 将 读 取 的 数 据 转 换 成 String String msg = new String(arr,0,length); // 输 出 System.out.print(msg); catch (IOException e) { // 文 件 不 存 在 异 常 System.out.println("File read error:" + e); finally { if (fis!= null) { try { fis.close(); catch (IOException e) { e.printstacktrace(); 当 读 取 英 文 文 档 时, 读 取 的 数 据 没 有 问 题, 结 果 如 下 图 : 但 取 得 中 文 文 档 时, 因 为 将 中 文 字 符 拆 分, 则 出 现 了 编 码 问 题, 结 果 如 下 图 : 第 260 页

261 如 果 采 用 字 符 流 读 取 数 据, 则 不 会 出 现 上 述 问 题 : FileInputStream fis = null; InputStreamReader reader = null; try { File f = new File("javakc.txt"); // 创 建 字 节 流 fis = new FileInputStream(f); // 创 建 字 符 流 reader = new InputStreamReader(fis); // 创 建 字 符 数 组, 每 次 读 取 5 个 字 符 char[] arr = new char[5]; // 读 取 的 字 符 长 度 int length = 0; while ((length = reader.read(arr))!= -1) { // 将 读 取 的 数 据 转 换 成 String String msg = new String(arr, 0, length); // 输 出 System.out.print(msg); catch (IOException e) { e.printstacktrace(); finally { if (reader!= null) { try { reader.close(); catch (IOException e) { e.printstacktrace(); 运 行 结 果 如 下 : 第 261 页

262 缓 冲 读 者 和 作 者 因 为 在 各 种 格 式 之 间 进 行 转 换 和 其 它 I/O 操 作 很 类 似, 所 以 在 处 理 大 块 数 据 时 效 率 最 高 在 InputStreamReader 和 OutputStreamWriter 的 结 尾 链 接 一 个 BufferedReader 和 BufferedWriter 是 一 个 好 主 意 记 住 对 BufferedWriter 使 用 flush() 方 法 FileInputStream fis = null; InputStreamReader reader = null; BufferedReader buf = null; try { File f = new File("javakc.txt"); // 创 建 字 节 流 fis = new FileInputStream(f); // 创 建 字 符 流 reader = new InputStreamReader(fis); buf = new BufferedReader(reader); String s = null; // 读 取 流 中 的 数 据 ( 按 行 读 取 ) while ((s = buf.readline())!= null) { System.out.println(s); catch (IOException e) { e.printstacktrace(); finally { if (buf!= null) { try { buf.close(); catch (IOException e) { e.printstacktrace(); 11.9 随 机 访 问 文 件 你 经 常 会 发 现 你 只 想 读 取 文 件 的 一 部 分 数 据, 而 不 需 要 从 头 至 尾 读 取 整 个 文 件 你 可 能 想 访 问 一 个 作 为 数 据 库 的 文 本 文 件, 此 时 你 会 移 动 到 某 一 条 记 录 并 读 取 它 的 数 据, 接 着 移 动 到 另 一 个 记 录, 然 后 再 到 其 他 记 录 每 一 条 记 录 都 位 于 文 件 的 不 同 部 分 Java 编 程 语 言 提 供 了 一 个 RandomAccessFile 类 来 处 理 这 种 类 型 的 输 入 输 出 你 可 以 用 如 下 两 种 构 造 方 法 来 打 开 一 个 随 机 存 取 文 件 : RandomAccessFile(String name, String mode); RandomAccessFile(File file, String mode); 第 262 页

263 mode 参 数 决 定 了 你 对 这 个 文 件 的 存 取 是 只 读 (r) 还 是 读 / 写 (rw) 例 如, 你 可 以 打 开 一 个 打 开 一 个 数 据 库 文 件 并 准 备 更 新 : RandomAccessFile raf; raf = new RandomAccessFile("javakc.txt","rw"); RandomAccessFile 对 象 按 照 与 数 据 输 入 输 出 对 象 相 同 的 方 式 来 读 写 信 息 你 可 以 访 问 在 DataInputStrem 和 DataOutputStream 中 所 有 的 read() 和 write() 操 作 Java 编 程 语 言 提 供 了 若 干 种 方 法, 用 来 帮 助 你 在 文 件 中 移 动 long getfilepointer() 返 回 文 件 指 针 的 当 前 位 置 void seek(long pos) 设 置 文 件 指 针 到 给 定 的 绝 对 位 置 这 个 位 置 是 按 照 从 文 件 开 始 的 字 节 偏 移 量 给 出 的 位 置 0 标 志 文 件 的 开 始 long length() 返 回 文 件 的 长 度 位 置 length() 标 志 文 件 的 结 束 在 文 件 末 尾, 写 入 字 符 : RandomAccessFile raf = null; try { File f = new File("javakc.txt"); raf = new RandomAccessFile(f, "rw"); raf.seek(f.length()); raf.write("welcome to Javakc!".getBytes()); catch (IOException e) { e.printstacktrace(); finally { if (raf!= null) { try { raf.close(); catch (IOException e) { e.printstacktrace(); 第 263 页

264 11.10 学 习 目 标 1. 理 解 File 类 封 装 的 是 文 件 的 抽 象 路 径 名, 并 且 不 能 操 作 文 件 的 内 容 2. 熟 练 使 用 File 类 的 主 要 方 法 ( 课 堂 上 老 师 讲 过 的 方 法 ) 3. 理 解 相 对 路 径 和 绝 对 路 径 4. File 类 的 Api 中, 有 的 返 回 文 件 路 径 名, 有 的 返 回 File, 理 解 其 本 质 是 一 样 的 比 如 getparent( ) 和 getparentfile( ),list( ) 和 listfiles( ) 5. 理 解 File 类 的 Api 中, 有 的 方 法 需 要 区 分 此 File 是 文 件 还 是 目 录 也 就 是 说 文 件 和 目 录 要 区 分 对 待, 比 如 list( ), 如 果 是 文 件 调 用 此 方 法 返 回 null, 如 果 目 录 调 用 此 方 法 返 回 数 组 作 业 1. 递 归 展 示 目 录 的 结 构 第 264 页

265 12 多 线 程 12.1 进 程 与 线 程 概 念 几 乎 每 种 操 作 系 统 都 支 持 进 程 的 概 念 进 程 就 是 在 某 种 程 度 上 相 互 隔 离 的 独 立 运 行 的 程 序, 每 一 个 进 程 都 有 自 己 独 立 的 内 存 空 间 比 如 IE 浏 览 器 程 序, 每 打 开 一 个 IE 浏 览 器 窗 口, 就 启 动 一 个 新 的 进 程 在 java 中, 我 们 执 行 java.exe 程 序, 就 启 动 一 个 独 立 的 Java 虚 拟 机 进 程, 该 进 程 的 任 务 就 是 解 析 并 执 行 Java 程 序 代 码 线 程 是 指 进 程 中 的 一 个 执 行 流 程, 一 个 进 程 可 以 由 多 个 线 程 组 成, 即 一 个 进 程 中 可 以 同 时 运 行 多 个 不 同 的 线 程, 它 们 分 别 执 行 不 同 的 任 务 当 进 程 内 的 多 个 线 程 同 时 运 行 时, 这 种 运 行 方 式 成 为 并 发 运 行 线 程 又 被 称 为 轻 量 级 进 程, 它 和 进 程 一 样 拥 有 独 立 的 执 行 控 制, 由 操 作 系 统 进 行 调 度 线 程 和 进 程 的 区 别 是 : 每 个 进 程 都 有 独 立 的 代 码 和 存 储 空 间 ( 进 程 上 下 文 ), 进 程 切 换 的 开 销 大 线 程 没 有 独 立 的 存 储 空 间, 而 是 和 所 属 进 程 中 其 他 的 线 程 共 享 代 码 和 存 储 空 间, 但 每 个 线 程 有 独 立 的 运 行 栈 和 程 序 计 数 器, 因 此 线 程 切 换 的 开 销 较 小 多 进 程 在 操 作 系 统 中 能 同 时 运 行 多 个 任 务 ( 程 序 ), 也 称 多 任 务 多 线 程 在 同 一 应 用 程 序 中 有 多 个 顺 序 流 同 时 执 行 许 多 服 务 器 程 序, 如 数 据 库 服 务 器 和 Web 服 务 器, 都 支 持 并 发 运 行, 这 些 服 务 器 能 同 时 响 应 来 自 不 同 客 户 的 请 求 java 线 程 的 运 行 机 制 在 java 虚 拟 机 进 程 中, 执 行 程 序 代 码 的 任 务 是 由 线 程 来 完 成 的 每 个 线 程 都 有 一 个 独 立 的 程 序 计 数 器 和 方 法 调 用 栈 程 序 计 数 器 : 也 称 为 PC 寄 存 器, 当 线 程 执 行 一 个 方 法 时, 程 序 计 数 器 指 向 方 法 区 中 下 一 条 要 执 行 的 字 节 码 指 令 方 法 调 用 栈 : 简 称 方 法 栈, 用 来 跟 踪 线 程 运 行 中 一 系 列 的 方 法 调 用 过 程, 栈 中 的 元 素 称 为 栈 帧, 每 当 线 程 调 用 一 个 方 法 的 时 候, 就 会 向 方 法 栈 压 入 一 个 新 帧 帧 用 来 存 储 方 法 的 参 数 局 部 变 量 和 运 算 过 程 中 的 临 时 数 据 栈 帧 由 以 下 三 个 部 分 组 成 : 局 部 变 量 区 : 存 放 局 部 变 量 和 方 法 参 数 第 265 页

266 操 作 数 栈 : 是 线 程 的 工 作 区, 用 来 存 放 运 算 过 程 中 生 成 的 临 时 数 据 栈 数 据 区 : 为 线 程 执 行 指 令 提 供 相 关 的 信 息, 包 括 如 何 定 位 到 位 于 堆 区 和 方 法 区 的 特 定 数 据, 以 及 如 何 正 常 退 出 方 法 或 者 异 常 中 断 方 法 每 当 用 Java 命 令 启 动 一 个 Java 虚 拟 机 进 程 时,Java 虚 拟 机 都 会 创 建 一 个 主 线 程, 该 线 程 从 程 序 入 口 main() 方 法 开 始 执 行 以 下 面 程 序 为 例, 介 绍 线 程 的 运 行 过 程 public class Test { private int num; // 实 例 变 量 public int add(){ int b=0; // 局 部 变 量 num++; b=num; return b; public static void main(string[] args) { Test t=new Test(); // 局 部 变 量 int num=0; // 局 部 变 量 num=t.add(); System.out.println(num); 主 线 程 从 main() 方 法 的 程 序 代 码 开 始 运 行, 当 它 开 始 执 行 method() 方 法 的 a++ 操 作 时, 运 行 时 数 据 区 的 状 态 如 下 图 所 示 Java 栈 区 add() 方 法 的 栈 帧 局 部 变 量 num 堆 区 Test 对 象 实 例 变 量 num 方 法 区 Test 类 的 数 据 结 构 add() 方 法 的 数 据 结 构 main() 方 法 的 栈 帧 局 部 变 量 t num++ 操 作 的 指 令 局 部 变 量 num 主 线 程 的 方 法 帧 主 线 程 的 的 程 序 计 数 器 main b=a 方 法 操 的 作 字 的 节 指 码 令 当 主 线 程 执 行 a++ 操 作 时, 它 能 根 据 method() 方 法 的 栈 帧 的 栈 数 据 区 中 的 有 关 信 息, 正 确 地 定 位 到 堆 区 的 Test 对 象 的 实 例 变 量 num, 并 把 它 的 值 加 1 当 add() 方 法 执 行 完 毕 后, 它 的 栈 帧 就 会 从 方 法 栈 中 弹 出, 它 的 局 部 变 量 b 结 束 生 命 周 期 main() 方 法 的 栈 帧 就 成 为 当 前 帧, 主 线 程 继 续 执 行 main() 方 法 方 法 区 存 放 了 线 程 所 执 行 的 字 节 码 指 令, 堆 区 存 放 了 线 程 所 操 作 的 数 据 ( 以 对 象 的 形 式 存 放 ), Java 栈 区 则 是 线 程 的 工 作 区, 保 存 线 程 的 运 行 状 态 第 266 页

267 另 外, 计 算 机 机 器 指 令 的 真 正 执 行 者 是 CPU, 线 程 必 须 获 得 CPU 的 使 用 权, 才 能 执 行 一 条 指 令 下 图 中 显 示 了 线 程 运 行 中 需 要 使 用 的 计 算 机 CPU 和 内 存 资 源 CPU 堆 区 的 数 据 方 法 区 的 代 码 Java 栈 区 的 方 法 调 用 栈 程 在 Java 的 方 法 中, 可 以 通 过 Thread 类 的 currentthread 方 法 得 到 正 在 调 用 该 方 法 的 线 public class Test { public static void main(string[] args) { Thread t=thread.currentthread(); System.out.println(" 调 用 main 方 法 的 线 程 名 字 是 :"+t.getname()); 虚 拟 机 为 调 用 main 方 法 的 线 程 命 名 为 main 12.2 线 程 的 创 建 和 启 动 Java 在 代 码 中 对 线 程 进 行 了 支 持, 程 序 员 可 以 创 建 自 己 的 线 程, 它 将 和 主 线 程 并 发 运 行 创 建 线 程 有 两 种 方 式 : 扩 展 Thread 类 实 现 Runnable 接 口 扩 展 Thread 类 Thread 类 代 表 线 程 类, 它 的 最 主 要 的 两 个 方 法 是 : run() 包 含 线 程 运 行 时 所 执 行 的 代 码 start() 用 于 启 动 线 程 开 发 线 程 类 只 需 要 继 承 Thread 类, 覆 盖 Thread 类 的 run() 方 法 即 可 在 Thread 类 中, run() 方 法 的 定 义 如 下 : public void run() 该 方 法 没 有 声 明 抛 出 任 何 异 常, 根 据 方 法 覆 盖 的 规 则,Thread 子 类 的 run() 方 法 也 不 能 声 明 抛 出 任 何 异 常 示 例 如 下 : 第 267 页

268 public class MyThread extends Thread { public void run(){ // 线 程 体 内 的 实 现 for(int i=0;i<100;i++){ System.out.println(i); public static void main(string[] args) { MyThread mt=new MyThread(); mt.start(); // 启 动 MyThread 线 程 当 执 行 java MyThread 命 令 时,Java 虚 拟 机 首 先 创 建 并 启 动 主 线 程 主 线 程 的 任 务 是 执 行 main 方 法,main 方 法 创 建 了 一 个 MyThread 对 象, 然 后 调 用 它 的 start() 方 法 启 动 MyThread 线 程 MyThread 线 程 的 任 务 是 执 行 它 的 run() 方 法 主 线 程 和 自 定 义 线 程 并 发 运 行 在 下 面 的 例 子 中,main 方 法 创 建 并 启 动 两 个 MyThread 线 程 : public class MyThread extends Thread { public void run(){ // 线 程 体 内 的 实 现 for(int i=0;i<100;i++){ // 打 印 线 程 的 名 字 System.out.println(this.getName()+":"+i); public static void main(string[] args) { MyThread mt=new MyThread(); MyThread mt2=new MyThread(); mt.start(); // 启 动 MyThread 线 程 mt2.start(); // 启 动 MyThread 线 程 执 行 结 果 : Thread-1:7 Thread-1:8 Thread-1:9 Thread-1:10 Thread-1:11 Thread-0:1 Thread-1:12 Thread-1:13 Thread-1:14 Thread-0:2 Thread-0:3 第 268 页

269 Thread-0:4 当 主 线 程 执 行 main() 方 法 时, 会 创 建 两 个 MyThread 对 象, 然 后 启 动 两 个 MyThread 线 程 在 Java 虚 拟 机 钟 有 两 个 线 程 并 发 执 行 MyThread 对 象 的 run() 方 法 在 两 个 线 程 各 自 的 方 法 栈 中 都 有 代 表 run() 方 法 的 栈 帧, 在 这 个 帧 中 存 放 了 局 部 变 量 num, 也 就 是 每 个 线 程 都 拥 有 自 己 的 局 部 变 量 num, 它 们 都 分 别 从 0 增 加 到 100 因 为 Thread 类 中 有 getname() 方 法,MyThread 类 继 承 了 Thread 类, 所 以 在 代 码 中 可 以 使 用 this.getname() 得 到 当 前 线 程 的 名 字 mt 对 象 启 动 线 程 的 名 字 是 Thread-0,mt2 对 象 启 动 线 程 的 名 字 是 Thread-1 从 运 行 结 果 上, 我 们 可 以 看 到 两 个 线 程 交 替 运 行, 两 个 线 程 轮 流 得 到 CPU 的 运 行 时 间 片 sleep 方 法 Thread 类 中 有 一 个 sleep 方 法, 在 指 定 的 毫 秒 数 内 让 当 前 正 在 执 行 的 线 程 休 眠 ( 暂 停 执 行 ), 就 是 线 程 睡 眠 一 定 的 时 间, 也 就 是 交 出 CPU 时 间 片, 根 据 参 数 来 决 定 暂 停 时 间 长 度, 让 给 等 待 序 列 中 的 下 一 个 线 程 Sleep 方 法 抛 出 InterruptedException public class MyThread extends Thread { public void run(){ for(int i=0;i<100;i++){ System.out.println(this.getName()+":"+i); try { // 让 当 前 线 程 休 眠 100 毫 秒 sleep(100); catch (InterruptedException e) { e.printstacktrace(); public static void main(string[] args) { MyThread mt=new MyThread(); MyThread mt2=new MyThread(); mt.start(); mt2.start(); 运 行 结 果 : Thread-0:0 Thread-1:0 Thread-1:1 Thread-0:1 Thread-1:2 Thread-0:2 Thread-1:3 Thread-0:3 第 269 页

270 Thread-1:4 Thread-0:4 Thread-1:5 当 Thread-0 线 程 执 行 打 印 后, 休 眠 100 毫 秒, 也 就 失 去 了 CPU 的 时 间 片,Thread-1 线 程 就 得 到 了 CPU 的 时 间 片, 执 行 了 打 印 操 作, 也 休 眠 100 毫 秒,100 毫 秒 后,Thread-0 线 程 先 恢 复 到 可 运 行 状 态, 接 着 运 行, 这 样 两 个 线 程 交 替 运 行 不 要 随 便 覆 盖 Thread 类 的 start() 方 法 创 建 一 个 线 程 对 象 后, 线 程 并 不 自 动 开 始 运 行, 必 须 调 用 它 的 start() 方 法 才 能 启 动 线 程 JDK 为 Thread 类 的 start() 方 法 提 供 了 默 认 的 实 现, 启 动 线 程 后 调 用 run() 方 法 如 果 不 通 过 start() 方 法 启 动 线 程, 而 是 直 接 调 用 run() 方 法, 那 只 是 普 通 的 方 法 调 用, 并 不 能 启 动 线 程 看 看 如 下 代 码 : public class MyThread extends Thread { public void run(){ for(int i=0;i<100;i++){ try { sleep(100); catch (InterruptedException e) { e.printstacktrace(); System.out.println(this.getName()+":"+i); public void start(){ run(); public static void main(string[] args) { MyThread mt=new MyThread(); MyThread mt2=new MyThread(); mt.start(); mt2.start(); 运 行 结 果 : Thread-0:0 Thread-0:1 Thread-0:2 Thread-0:99 Thread-1:0 Thread-1:1 Thread-1:3 Thread-1:4 当 主 线 程 main 执 行 start() 方 法 时,start() 方 法 并 没 有 启 动 MyThread 线 程, 而 是 直 第 270 页

271 接 调 用 了 run() 方 法, 这 只 是 普 通 的 方 法 调 用 第 一 个 run() 方 法 执 行 完 成 后, 才 开 始 调 用 第 二 个 run() 方 法, 并 没 有 出 现 两 个 线 程 并 发 运 行 的 情 况 所 以, 在 Thread 子 类 中 不 要 随 意 覆 盖 start() 方 法, 假 如 一 定 要 覆 盖 start() 方 法, 那 么 应 该 先 调 用 super.start() 方 法 public class MyThread extends Thread { public static int count=0; public void run(){ for(int i=0;i<100;i++){ try { sleep(100); catch (InterruptedException e) { e.printstacktrace(); public void start(){ super.start(); System.out.println(" 第 "+(++count)+" 线 程 启 动 了 "); 一 个 线 程 只 能 被 启 动 一 次 一 个 线 程 只 能 被 启 动 一 次, 以 下 代 码 视 图 两 次 启 动 MyThread 线 程 MyThread mt=new MyThread(); mt.start(); mt.start(); // 抛 出 IllegalThreadStateException 异 常 第 二 次 调 用 mt.start() 方 法 时, 会 抛 出 java.lang.illegalthreadstateexception 异 常 实 现 Runnable 接 口 Java 类 不 允 许 一 个 类 继 承 多 个 类, 因 此 一 旦 一 个 类 继 承 了 Thread 类, 就 不 能 再 继 承 其 他 的 类, 为 了 解 决 这 一 问 题,Java 提 供 了 java.lang.runnable 接 口, 它 有 一 个 run() 方 法, 定 义 如 下 : public void run() 示 例 中 MyThread 类 实 现 了 Runnable 接 口,run() 方 法 表 示 线 程 所 执 行 的 代 码 public class MyThread implements Runnable { int count=0; public void run(){ while(true){ System.out.println(Thread.currentThread().getName()+":"+count++); if(count>10){ 第 271 页

272 break;// 当 count 大 于 10 的 时 候, 循 环 结 束 try { Thread.sleep(100); catch (InterruptedException e) { e.printstacktrace(); public static void main(string[] args) { MyThread mt=new MyThread(); Thread t1=new Thread(mt); Thread t2=new Thread(mt); t1.start(); t2.start(); 在 Thread 类 中 定 义 了 如 下 形 式 的 构 造 方 法 : public Thread(Runnable runnable) 当 线 程 启 动 时, 将 执 行 参 数 runnable 所 引 用 对 象 的 run() 方 法 其 实 Thread 类 也 实 现 了 Runnable 接 口 在 示 例 中, 主 线 程 创 建 了 t1 和 t2 两 个 线 程 对 象 启 动 t1 和 t2 线 程 将 执 行 MyThread 对 象 的 run() 方 法 t1 和 t2 共 享 同 一 个 MyThread 对 象, 在 执 行 run() 方 法 时 将 操 作 同 一 个 实 例 变 量 count 打 印 结 果 如 下 : Thread-0:0 Thread-1:1 Thread-0:2 Thread-1:9 Thread-0:10 Thread-1:11 将 main() 做 如 下 修 改 : public static void main(string[] args) { MyThread mt1=new MyThread(); MyThread mt2=new MyThread(); Thread t1=new Thread(mt1); Thread t2=new Thread(mt2); t1.start(); t2.start(); t1 和 t2 线 程 启 动 后, 将 分 别 执 行 mt1 和 mt2 变 量 所 引 用 的 MyThread 对 象 的 run() 方 法, 因 此 t1 和 t2 线 程 操 作 不 同 的 MyThread 对 象 的 实 例 变 量 count 运 行 结 果 如 下 : Thread-0:0 Thread-1:0 第 272 页

273 Thread-0:1 Thread-1:1 Thread-0:2 Thread-0:8 Thread-1:9 Thread-0:9 Thread-0:10 Thread-1: 线 程 的 状 态 转 换 新 建 状 态 (New) 用 new 语 句 创 建 的 线 程 对 象 处 于 新 建 状 态, 此 时 和 其 他 Java 对 象 一 样, 仅 仅 在 堆 区 中 被 分 配 了 内 存 就 绪 状 态 (Runnable) 当 一 个 线 程 对 象 创 建 后, 其 他 线 程 调 用 它 的 start() 方 法, 该 线 程 就 进 入 了 就 绪 状 态, Java 虚 拟 机 会 为 它 创 建 方 法 调 用 栈 和 程 序 计 数 器 处 于 这 个 状 态 的 线 程 位 于 可 运 行 池 中, 等 待 获 得 CPU 的 使 用 权 运 行 状 态 (Running) 处 于 这 个 状 态 的 线 程 占 用 CPU, 执 行 程 序 代 码 在 并 发 运 行 环 境 中, 如 果 计 算 机 只 有 一 个 CPU, 那 么 任 何 时 刻 只 会 有 一 个 线 程 处 于 这 个 状 态 如 果 计 算 机 有 多 个 CPU, 那 么 同 一 时 刻 可 以 让 几 个 线 程 占 用 不 同 的 CPU, 使 它 们 都 处 于 运 行 状 态 只 有 处 于 就 绪 状 态 的 线 程 才 有 机 会 转 到 运 行 状 态 阻 塞 状 态 (Blocked) 阻 塞 状 态 是 指 线 程 因 为 某 些 原 因 放 弃 CPU, 暂 时 停 止 运 行 当 线 程 处 于 阻 塞 状 态 时,Java 虚 拟 机 不 会 给 线 程 分 配 CPU, 直 到 线 程 重 新 进 入 就 绪 状 态, 才 有 机 会 转 到 运 行 状 态 阻 塞 状 态 可 以 分 为 以 下 3 种 : 位 于 对 象 等 待 池 中 的 阻 塞 状 态 : 当 线 程 处 于 运 行 状 态 时, 如 果 执 行 了 wait() 方 法,Java 虚 拟 机 就 会 把 线 程 放 到 等 待 池 中 位 于 对 象 锁 池 中 的 阻 塞 状 态 : 当 线 程 处 于 运 行 状 态 时, 试 图 获 得 某 个 对 象 的 同 步 锁 时, 如 果 第 273 页

274 该 对 象 的 同 步 锁 已 经 被 其 他 线 程 占 用,Java 虚 拟 机 就 会 把 这 个 线 程 放 到 锁 池 中 其 他 的 阻 塞 状 态 : 当 前 线 程 执 行 了 sleep() 方 法, 或 者 调 用 了 其 他 线 程 的 join() 方 法, 或 者 发 出 了 I/O 请 求 时, 就 会 进 入 这 个 状 态 当 一 个 线 程 执 行 System.out.println() 或 者 System.in.read() 方 法 时, 就 会 发 出 一 个 I/O 请 求, 该 线 程 放 弃 CPU, 进 入 阻 塞 状 态, 知 道 I/O 处 理 完 毕, 该 线 程 才 会 恢 复 运 行 import java.io.ioexception; class MyThread extends Thread { int count = 0; public void run() { while (true) { System.out.println(getName() + ":" + count++); try { Thread.sleep(3000); catch (InterruptedException e) { e.printstacktrace(); class YourThread extends Thread { public void run() { while (true) { try { System.out.println(" 等 待 用 户 输 入 "); int data = System.in.read(); System.out.println(getName() + " 用 户 输 入 了 :"+ data); catch (IOException e) { e.printstacktrace(); class Client { public static void main(string[] arr) { MyThread mt=new MyThread(); YourThread yt=new YourThread(); mt.start(); yt.start(); 运 行 结 果 : Thread-0:0 等 待 用 户 输 入 Thread-0:1 第 274 页

275 Thread-0:2 a Thread-1 用 户 输 入 了 :97 等 待 用 户 输 入 Thread-1 用 户 输 入 了 :13 等 待 用 户 输 入 Thread-1 用 户 输 入 了 :10 等 待 用 户 输 入 Thread-0:3 Thread-0:4 在 上 面 的 示 例 中, 主 线 程 main 启 动 了 mt 和 yt 两 个 线 程 mt 线 程 启 动 后, 运 行 了 一 次, 进 入 休 眠 的 阻 塞 状 态 yt 线 程 得 到 时 间 片, 开 始 运 行 输 出 了 等 待 用 户 输 入, 之 后 进 入 了 I/O 请 求 的 阻 塞 状 态, 等 待 用 户 的 输 入 mt 线 程 又 得 到 时 间 片, 执 行 后 又 休 眠, 这 样 重 复 了 两 次 用 户 输 入 了 a 和 回 车,yt 由 阻 塞 状 态 变 为 运 行 状 态, 连 续 打 印 出 用 户 输 入 的 值 后, 又 进 入 I/O 请 求 的 阻 塞 状 态 mt 线 程 又 得 到 时 间 片, 继 续 运 行 死 亡 状 态 (Dead) 当 线 程 退 出 run( 方 法 ) 时, 就 进 入 死 亡 状 态, 表 示 该 线 程 结 束 生 命 周 期 线 程 有 可 能 是 正 常 执 行 完 run() 方 法 而 退 出 的, 也 有 可 能 是 遇 到 异 常 而 退 出 不 管 线 程 正 常 结 束 还 是 异 常 结 束, 都 不 会 对 其 他 线 程 造 成 影 响 在 下 面 的 示 例 中,MyThread 线 程 在 运 行 时 因 为 抛 出 RuntimeException 异 常 而 结 束, 此 时 主 线 程 main 正 常 运 行 class MyThread extends Thread { int count = 0; public void run() { while (true) { System.out.println(getName() + ":" + count++); try { Thread.sleep(3000); if(count==3){ throw new RuntimeException(); catch (InterruptedException e) { e.printstacktrace(); 第 275 页

276 class Client { public static void main(string[] arr) throws InterruptedException { MyThread mt=new MyThread(); mt.start(); while(true){ System.out.println(Thread.currentThread().getName()+":is alive===="+mt.isalive()); Thread.sleep(3000); Thread 类 的 isalive() 方 法 能 判 断 一 个 线 程 是 否 活 着, 当 线 程 处 于 死 亡 状 态 活 着 新 建 状 态 时, 该 方 法 返 回 false, 在 其 余 状 态 下, 该 方 法 返 回 true 运 行 结 果 : Thread-0:0 main:is alive====true main:is alive====true Thread-0:1 main:is alive====true Thread-0:2 main:is alive====true Exception in thread "Thread-0" java.lang.runtimeexception at MyThread.run(Client.java:13) main:is alive====false main:is alive====false 12.4 线 程 的 调 度 计 算 机 通 常 只 有 一 个 CPU, 在 任 何 时 刻 只 能 执 行 一 条 机 器 指 令, 每 个 线 程 只 有 获 得 CPU 的 使 用 权 才 能 执 行 指 令 所 谓 多 线 程 的 并 发, 其 实 是 指 宏 观 上 看, 各 个 线 程 轮 流 获 得 CPU 的 使 用 权, 分 别 执 行 各 自 的 任 务 在 可 运 行 池 中, 会 有 多 个 处 于 就 绪 状 态 的 线 程 等 待 CPU,Java 虚 拟 机 的 一 项 任 务 就 是 负 责 线 程 的 调 度 线 程 的 调 度 是 指 按 照 特 定 的 机 制 为 多 个 线 程 分 配 CPU 的 使 用 权 有 两 种 调 度 模 型 : 分 时 调 度 模 型 和 抢 占 式 调 度 模 型 分 时 调 度 模 型 是 指 让 所 有 线 程 轮 流 获 得 CPU 的 使 用 权, 并 且 平 均 分 配 每 个 线 程 占 用 CPU 的 时 间 片 Java 虚 拟 机 采 用 抢 占 式 调 度 模 型, 是 指 优 先 让 可 运 行 池 中 优 先 级 高 的 线 程 占 用 CPU, 如 果 可 运 行 池 中 线 程 的 优 先 级 相 同, 那 么 就 随 机 选 择 一 个 线 程, 使 其 占 用 CPU 处 于 运 行 状 态 的 线 程 会 一 直 运 行, 直 至 它 不 得 不 放 弃 CPU 一 个 线 程 会 因 为 一 下 原 因 而 放 弃 CPU: Java 虚 拟 机 让 当 前 线 程 暂 时 放 弃 CPU, 转 到 就 绪 状 态, 使 其 他 的 线 程 获 得 运 行 机 会 当 前 线 程 因 为 某 些 原 因 而 进 入 阻 塞 状 态 第 276 页

277 线 程 运 行 结 束 值 得 注 意 的 是, 线 程 的 调 度 不 是 跨 平 台 的, 它 不 仅 取 决 于 Java 虚 拟 机, 还 依 赖 操 作 系 统 在 某 些 操 作 系 统 中, 只 要 运 行 中 的 线 程 没 有 遇 到 阻 塞, 也 会 在 运 行 一 段 时 间 后 放 弃 CPU, 给 其 他 线 程 运 行 的 机 会 在 java 中, 同 时 启 动 多 个 线 程 后, 不 能 保 证 各 个 线 程 轮 流 获 得 均 等 的 CPU 时 间 片, 从 之 前 的 例 子 中, 大 家 可 以 体 会 到 这 一 点 一 个 线 程 运 行 机 毫 秒 后, 就 放 弃 的 CPU 时 间 片, 另 一 个 线 程 就 得 到 了 CPU 时 间 片, 各 个 线 程 交 替 运 行 以 下 程 序 可 以 证 明 这 一 点 : class MyThread extends Thread { int count = 0; public void run() { while (true) { System.out.print(getName() + ":" + count++ +","); class Client { public static void main(string[] arr){ MyThread mt=new MyThread(); MyThread mt2=new MyThread(); mt.start(); mt2.start(); 两 个 线 程 抢 占 时 间 片 的 结 果 如 下 : Thread-0:0,Thread-0:1,Thread-0:2,,Thread-0:7,Thread-0:8,Thread -0:9, Thread-1:0, Thread-0:10,Thread-1:1,Thread-0:11,Thread-0:12,Thread-0:13,Thread-1:2, Thread-0:14, Thread-1:3,Thread-0:15,Thread-1:4,Thread-0:16,Thread-1:5, Thread-0:17,Thread-0:18,Thread-0:19,Thread-0:20,Thread-0:21,Thread-0:2 2,Thread-0:23, Thread-1:6,Thread-1:7,Thread-1:8,Thread-1:9,Thread-1:10, Thread-0:24,Thread-0:25,Thread-0:26,Thread-0:27, Thread-1:11,Thread-1:12,Thread-1:13,,Thread-1:16,Thread-1:17,Thr ead-0:28,thread-1:18, 如 果 通 过 代 码, 希 望 明 确 地 让 一 个 线 程 给 另 外 一 个 线 程 运 行 的 机 会, 可 以 采 用 以 下 方 法 之 一 : 调 整 各 个 线 程 的 优 先 级 让 处 于 运 行 状 态 的 线 程 调 用 Thread.sleep() 方 法 让 处 于 运 行 状 态 的 线 程 调 用 Thread.yield() 方 法 第 277 页

278 让 处 于 运 行 状 态 的 线 程 调 用 另 一 个 线 程 的 join() 方 法 调 整 各 个 线 程 的 优 先 级 所 有 处 于 就 绪 状 态 的 线 程 根 据 优 先 级 存 放 在 可 运 行 池 中, 优 先 级 低 的 线 程 获 得 较 少 的 运 行 机 会, 优 先 级 高 的 线 程 获 得 较 多 的 运 行 机 会 Thread 类 的 setpriority(int) 和 getpriority() 方 法 分 别 用 来 设 置 优 先 级 和 读 取 优 先 级 优 先 级 用 整 数 表 示, 取 值 范 围 是 1~10,Thread 类 有 以 下 3 个 静 态 常 量 MAX_PRIORITY: 取 值 为 10, 表 示 最 高 优 先 级 MIN_PRIORITY: 取 值 为 1, 表 示 最 低 优 先 级 NORM_PRIORITY: 取 值 为 5, 表 示 默 认 的 优 先 级 修 改 之 前 的 代 码, 分 别 设 置 两 个 线 程 的 优 先 级 class MyThread extends Thread { int count = 0; public void run() { while (true) { System.out.print(getName() + ":" + count++ +","); class Client { public static void main(string[] arr){ MyThread mt=new MyThread(); MyThread mt2=new MyThread(); mt.setpriority(thread.max_priority);// 设 置 最 高 的 优 先 级 mt2.setpriority(thread.min_priority);// 设 置 最 低 的 优 先 级 mt.start(); mt2.start(); 由 于 mt(thread-0) 线 程 的 优 先 级 高 于 mt2(thread-1) 线 程 的 优 先 级, 因 此 前 者 优 先 获 得 CPU 的 使 用 权, 运 行 结 果 如 下 : Thread-0:0,Thread-1:0,Thread-0:1, Thread-1:1, Thread-0:2, Thread-1:2, Thread-0:3,Thread-0:4,Thread-0:5,Thread-0:6,Thread-0:7,Thread-0:8,Thre ad-0:9, Thread-0:305,Thread-0:306,Thread-0:307,Thread-0:308,Thread-0:309,Threa d-0:310, 第 278 页

279 Thread-1:3, Thread-0:311, Thread-1:4, Thread-0:312,Thread-0:313,Thread-0:314,Thread-0:315,Thread-0:316,Threa d-0:317, Thread-0:995,Thread-0:996,Thread-0:997,Thread-0:998,Thread-0:999,Threa d-0:1000, Thread-1:21,Thread-1:22,Thread-1:23,Thread-1:24,Thread-1:25,Thread-1:2 6, Thread-1:996,Thread-1:997,Thread-1:998,Thread-1:999,Thread-1:1000, 在 两 个 线 程 同 时 运 行 的 时 候, 每 当 mt2(thread-1) 线 程 获 得 时 间 片 后, 往 往 只 运 行 一 次, 就 放 弃 了 CPU 的 时 间 片, 所 以 mt(thread-0) 线 程 最 先 运 行 完 毕 如 果 不 设 置 线 程 的 优 先 级, 线 程 默 认 的 优 先 级 为 5 值 得 注 意 的 是, 尽 管 Java 提 供 了 10 个 优 先 级, 但 它 与 多 数 操 作 系 统 都 不 能 很 好 地 映 射 比 如 Windows2000 有 7 个 优 先 级, 并 且 不 是 固 定 的, 而 Sun 公 司 的 Solaris 操 作 系 统 有 2 的 31 次 方 个 优 先 级 如 果 希 望 程 序 能 移 植 到 各 个 操 作 系 统 中, 应 该 确 保 在 设 置 线 程 的 优 先 级 时, 只 使 用 MAX_PRIORITY MIN_PRIORITY NORM_PRIORITY 这 3 个 优 先 级 这 样 才 能 保 证 在 不 同 的 操 作 系 统 中, 对 同 样 优 先 级 的 线 程 采 用 同 样 的 调 度 方 式 线 程 睡 眠 :Thread.sleep() 方 法 当 一 个 线 程 在 运 行 过 程 中 执 行 了 sleep() 方 法 时, 它 就 会 放 弃 CPU, 转 到 阻 塞 状 态 下 面 示 例 中 每 执 行 一 次 循 环, 就 睡 眠 1000 毫 秒 class MyThread extends Thread { int count = 0; public void run() { while (true) { System.out.print(getName() + ":" + count++); try { sleep(1000);// 睡 眠 1 秒 钟 catch (InterruptedException e) { e.printstacktrace(); class Client { public static void main(string[] arr) { MyThread mt=new MyThread(); mt.start(); 第 279 页

280 Thread 类 的 sleep(long millis) 方 法 是 静 态 的,millis 参 数 设 定 睡 眠 的 时 间, 以 毫 秒 为 单 位 当 执 行 sleep() 方 法 时, 就 会 放 弃 CPU 开 始 睡 眠,1 秒 钟 后 线 程 结 束 睡 眠, 就 会 获 得 CPU, 继 续 进 行 下 一 次 循 环 所 以 会 感 觉 程 序 运 行 很 慢 值 得 注 意 的 是, 当 某 线 程 结 束 睡 眠 后, 首 先 转 到 就 绪 状 态, 假 如 其 他 的 线 程 正 在 占 用 CPU, 那 么 该 线 程 就 在 可 运 行 池 中 等 待 获 得 CPU 线 程 在 睡 眠 中 如 果 被 中 断, 就 会 收 到 一 个 InterrupedException 异 常, 线 程 就 会 跳 到 异 常 处 理 代 码 块 把 InterrupedException 异 常 包 装 成 一 个 RuntionException, 然 后 继 续 将 它 抛 出 在 下 面 的 示 例 中, 主 线 程 调 用 interrupt() 方 法 中 断 了 睡 眠 中 的 mt 线 程,mt 线 程 就 抛 出 了 InterrupedException 异 常 class MyThread extends Thread { int count = 0; public void run() { while (true) { System.out.println(getName() + ":" + count++); try { sleep(5000);// 休 眠 5 秒 钟 catch (InterruptedException e) { e.printstacktrace(); class Client { public static void main(string[] arr) throws InterruptedException { MyThread mt=new MyThread(); mt.start(); Thread.sleep(1000); mt.interrupt();// 中 断 mt 线 程 的 睡 眠 运 行 结 果 如 下 : Thread-0:0 Thread-0:1java.lang.InterruptedException: sleep interrupted at java.lang.thread.sleep(native Method) at MyThread.run(Client.java:10) Thread-0:2 Thread-0:3 Thread-0:4 可 以 看 到 主 线 程 main 欲 中 断 正 在 睡 眠 中 的 mt 线 程, 因 为 线 程 mt 正 在 睡 眠, 所 以 中 断 失 败, 报 出 错 误, 线 程 mt 醒 来 后, 还 可 以 继 续 运 行 interrupt() 方 法 对 于 正 在 运 行 中 的 线 程 ( 不 是 睡 眠 中 的 线 程 ) 是 不 起 作 用 的, 只 有 对 阻 塞 第 280 页

281 中 的 线 程 有 效 线 程 让 步 :Thread.yield() 方 法 当 线 程 在 运 行 中 执 行 了 Thread 类 的 yield() 静 态 方 法, 如 果 此 时 具 有 相 同 优 先 级 的 其 他 线 程 处 于 就 绪 状 态, 那 么 yield() 方 法 将 把 当 前 运 行 的 线 程 放 到 可 运 行 池 中 并 使 另 一 个 线 程 运 行 如 果 没 有 相 同 优 先 级 的 可 运 行 线 程, 则 yield() 方 法 什 么 也 不 做 下 面 代 码 中, 线 程 执 行 完 一 次 循 环 后, 就 执 行 了 yield() 方 法 class MyThread extends Thread { int count = 0; public void run() { while (true) { System.out.println(getName() + ":" + count++); yield(); class Client { public static void main(string[] arr) throws InterruptedException { MyThread mt=new MyThread(); MyThread mt2=new MyThread(); mt.start(); mt2.start(); 从 运 行 结 果 中, 我 们 可 以 看 到 两 个 线 程 交 替 运 行 Thread-0:0 Thread-1:0 Thread-0:1 Thread-1:1 Thread-0:2 Thread-1:2 Thread-0:3 Thread-1:3 sleep() 方 法 和 yield() 方 法 都 是 Thread 类 的 静 态 方 法, 都 会 使 当 前 处 于 运 行 状 态 的 线 程 放 弃 CPU, 把 运 行 机 会 让 给 其 他 线 程 两 者 的 区 别 在 于 : sleep() 方 法 会 给 其 他 线 程 运 行 机 会, 而 不 考 虑 其 他 线 程 的 优 先 级, 因 此 会 给 较 低 优 先 级 线 程 一 个 机 会 ;yield() 方 法 只 会 给 相 同 优 先 级 或 者 更 高 优 先 级 线 程 一 个 运 行 的 机 会 当 线 程 执 行 了 sleep(long millis) 方 法 后, 会 转 到 阻 塞 状 态, 参 数 millis 指 定 睡 眠 的 时 间 ; 当 线 程 执 行 了 yield() 方 法 后, 将 转 到 就 绪 状 态 第 281 页

282 异 常 sleep() 方 法 方 法 抛 出 InterrupedException 异 常, 而 yield() 方 法 没 有 声 明 抛 出 任 何 sleep() 方 法 比 yield() 方 法 具 有 更 好 的 可 移 植 性 不 能 依 靠 yield() 方 法 来 提 高 程 序 的 并 发 性 能 对 于 大 多 数 程 序 员 来 说,yield() 方 法 的 唯 一 用 途 是 在 测 试 期 间 人 为 地 提 高 程 序 的 并 发 性 能, 以 帮 助 发 现 一 些 隐 藏 的 错 误 等 待 其 他 线 程 结 束 :join() 当 前 运 行 的 线 程 可 以 调 用 另 一 个 线 程 的 join() 方 法, 当 前 运 行 的 线 程 将 转 到 阻 塞 状 态, 直 至 另 一 个 线 程 运 行 结 束, 它 才 恢 复 运 行 class MyThread extends Thread { int count = 0; public void run() { while (count<5) { System.out.println(getName() + ":" + count++); class Client { public static void main(string[] arr) throws InterruptedException { MyThread mt=new MyThread(); mt.setname("mt"); mt.start(); mt.join();// 主 线 程 等 待 mt 线 程 的 运 行 结 束 System.out.println("main end"); 主 线 程 调 用 了 mt 线 程 的 join() 方 法, 主 线 程 将 等 到 mt 线 程 运 行 结 束 后, 才 能 恢 复 运 行 mt:0 mt:1 mt:2 mt:3 mt:4 main end join() 方 法 有 两 种 重 载 形 式 : public void join() public void join(long timeout) timeout 参 数 设 定 当 前 线 程 被 阻 塞 的 时 间, 以 毫 秒 为 单 位 如 果 把 示 例 main() 方 法 中 的 mt.join() 改 为 mt.join(10), 那 么 当 主 线 程 被 阻 塞 的 时 间 超 过 了 10 毫 秒, 或 者 mt 线 程 运 行 结 束 时, 主 线 程 就 会 恢 复 运 行 第 282 页

283 12.5 获 得 当 前 线 程 对 象 的 引 用 Thread 类 的 currentthread() 静 态 方 法 返 回 当 前 线 程 对 象 的 引 用 在 主 线 程 main 中 执 行 currentthread() 方 法 时, 返 回 主 线 程 对 象 的 引 用 class Client { public static void main(string[] arr) { Thread main=thread.currentthread(); System.out.println(main.getName()); 12.6 后 台 线 程 演 员 在 前 台 演 戏, 许 多 工 作 人 员 在 后 台 为 演 员 提 供 服 务, 例 如 灯 光 音 效, 当 演 出 结 束 后, 后 台 的 服 务 也 就 停 止 了 有 一 点 需 要 注 意 一 下, 是 演 员 演 戏 先 停 止, 后 台 服 务 再 停 止 后 台 线 程 是 指 为 其 他 线 程 提 供 服 务 的 线 程, 也 成 为 守 护 线 程 如 果 说 演 员 是 前 台 线 程, 那 么 其 他 工 作 人 员 就 是 后 台 线 程 Java 虚 拟 机 的 垃 圾 回 收 线 程 就 是 典 型 的 后 台 线 程, 它 负 责 回 收 其 他 线 程 不 再 使 用 的 内 存 后 台 线 程 的 特 点 是 : 后 台 线 程 和 前 台 线 程 相 伴 相 随, 只 有 前 台 线 程 都 结 束 生 命 周 期, 后 台 线 程 才 会 结 束 生 命 周 期 只 要 有 一 个 前 台 线 程 还 没 有 结 束 运 行, 后 台 线 程 就 不 会 结 束 生 命 周 期 主 线 程 在 默 认 情 况 下 是 前 台 线 程, 由 前 台 线 程 创 建 的 线 程 在 默 认 情 况 下 也 是 前 台 线 程 调 用 Thread 类 的 setdaemon(true) 方 法, 就 能 把 一 个 线 程 设 置 为 后 台 线 程 Thread 类 的 isdaemon() 方 法 用 来 判 读 一 个 线 程 是 否 是 后 台 线 程 在 下 面 的 例 子 中 没 有 设 置 后 台 线 程, 当 main 线 程 结 束 后,mt 线 程 继 续 运 行 class MyThread extends Thread { int count = 0; public void run() { while (true) { try { sleep(1000); catch (InterruptedException e) { e.printstacktrace(); System.out.println(getName() + ":" + count++); class Client { public static void main(string[] arr) throws InterruptedException { MyThread mt=new MyThread(); 第 283 页

284 mt.setname("mt"); mt.start(); Thread.sleep(5000); System.out.println("main end"); 运 行 结 果 如 下 : mt:0 mt:1 mt:2 mt:3 main end mt:4 mt:5 如 果 设 置 mt 线 程 为 后 台 线 程 : public static void main(string[] arr) throws InterruptedException { MyThread mt=new MyThread(); mt.setname("mt"); mt.setdaemon(true);// 设 置 mt 线 程 为 后 台 线 程 mt.start(); Thread.sleep(5000); System.out.println("main end"); 运 行 结 果 如 下 : mt:0 mt:1 mt:2 mt:3 mt:4 main end 尽 管 后 台 线 程 的 run() 方 法 执 行 的 是 无 限 循 环, 只 要 当 main 线 程 睡 眠 5 秒 钟 结 束 后,mt 线 程 也 就 结 束 了 在 使 用 后 台 线 程 时, 有 以 下 注 意 点 : Java 虚 拟 机 保 证 : 当 所 有 前 台 线 程 运 行 结 束 后, 再 终 止 后 台 线 程, 体 现 的 是 先 后 顺 序 那 么 前 台 线 程 运 行 结 束 后, 后 台 线 程 是 一 次 也 不 运 行 吗? 这 取 决 于 程 序 的 实 现 只 有 线 程 启 动 前 ( 即 调 用 start() 方 法 以 前 ), 才 能 把 它 设 置 为 后 台 线 程 如 果 线 程 启 动 后, 再 调 用 这 个 线 程 的 setdaemon() 方 法, 就 会 导 致 IllegalThreadStateException 异 常 由 于 前 台 线 程 创 建 的 线 程 在 默 认 情 况 下 仍 然 是 前 台 线 程, 由 后 台 线 程 创 建 的 线 程 在 默 认 情 况 下 仍 然 是 后 台 线 程 第 284 页

285 12.7 定 时 器 Timer 在 JDK 的 java.util 包 中 提 供 了 一 个 实 用 类 Timer, 它 能 够 定 时 执 行 特 定 的 任 务 TimerTask 类 表 示 定 时 器 执 行 的 一 项 任 务 class Client { public static void main(string[] arr) throws InterruptedException { Timer timer=new Timer(); TimerTask task=new TimerTask(){ public void run(){ System.out.println("time is:"+new Date()); ; timer.schedule(task,10,5000);// 设 置 定 时 任 务 java.util.timertask 类 是 一 个 抽 象 类, 它 实 现 了 Runnable 接 口 run() 方 法 表 示 定 时 器 需 要 完 成 的 任 务 Timer 类 的 schedule(timertask task,long delay,long period) 方 法 用 来 设 置 定 时 器 需 要 执 行 的 任 务 task 参 数 表 示 任 务 ;delay 参 数 表 示 延 迟 执 行 的 时 间, 以 毫 秒 为 单 位 ; period 参 数 表 示 每 次 执 行 任 务 的 间 隔 时 间, 以 毫 秒 为 单 位 例 如 : timer.schedule(task,10,5000); 以 上 代 码 表 示 定 时 器 将 在 10 毫 秒 后 开 始 执 行 task 任 务, 以 后 每 隔 5000 毫 秒 重 复 执 行 一 次 task 任 务 同 一 个 定 时 器 对 象 可 以 执 行 多 个 定 时 任 务, 例 如 : timer.schedule(task1,0,5000); timer.schedule(task2,0,3000); 以 上 代 码 表 示 定 时 器 会 执 行 两 个 任 务, 第 一 个 任 务 每 隔 5 秒 执 行 一 次, 第 二 个 任 务 每 隔 3 秒 执 行 一 个 12.8 线 程 的 同 步 线 程 的 职 责 就 是 执 行 一 些 操 作, 而 多 数 操 作 都 涉 及 到 处 理 数 据 下 面 的 线 程 的 操 作 主 要 是 处 理 实 例 变 量 count 通 过 四 个 线 程 模 拟 卖 票 系 统 class TicketSell implements Runnable{ // 有 100 张 票 int count=100; public void run(){ while(true){ if(count>0){ try{ Thread.sleep(10); catch(exception e){ 第 285 页

286 System.out.println(Thread.currentThread().getName() +"="+count); count--; else{ break; class Client { public static void main(string[] arr){ TicketSell ts=new TicketSell(); Thread t1=new Thread(ts); Thread t2=new Thread(ts); Thread t3=new Thread(ts); Thread t4=new Thread(ts); // 启 动 四 个 线 程 卖 票 t1.start(); t2.start(); t3.start(); t4.start(); 运 行 结 果 如 下 : Thread-1=100 Thread-0=99 Thread-3=98 Thread-0=3 Thread-3=2 Thread-2=1 Thread-1=0 Thread-3=-1 Thread-0=-1 票 的 数 量 count 是 一 个 共 享 资 源, 四 个 线 程 对 共 享 资 源 开 始 了 竞 争 当 线 程 Thread-2 卖 掉 最 后 一 张 票 后, 其 他 的 三 个 线 程, 还 认 为 有 最 后 一 张 票, 继 续 卖 票, 造 成 了 共 享 资 源 的 并 发 问 题 以 上 卖 票 的 操 作 被 称 为 原 子 操 作, 一 个 线 程 在 执 行 原 子 操 作 期 间, 应 该 采 取 措 施 使 得 其 他 线 程 不 能 操 作 共 享 资 源, 否 则 就 会 出 现, 共 享 资 源 被 重 复 操 作 的 问 题 同 步 代 码 块 为 了 保 证 每 个 线 程 能 正 常 执 行 原 子 操 作,Java 引 入 了 同 步 机 制, 具 体 做 法 是 在 代 表 原 子 操 作 的 程 序 代 码 前 加 上 synchronized 标 记, 这 样 的 代 码 被 称 为 同 步 代 码 块 第 286 页

287 class TicketSell implements Runnable{ // 有 100 张 票 int count=100; // 同 步 锁 Object o=new Object(); public void run(){ while(true){ synchronized(o){ if(count>0){ try{ Thread.sleep(10); catch(exception e){ System.out.println(Thread.currentThread().getName() +"="+count); count--; else{ break; 以 上 代 码 创 建 了 Object 对 象 o, 在 同 步 块 中,o 充 当 了 同 步 锁 的 作 用 每 个 Java 对 象 都 有 且 只 有 一 个 同 步 锁, 在 任 何 时 刻, 最 多 只 允 许 一 个 线 程 拥 有 这 把 锁 当 第 一 个 线 程 拥 有 了 这 个 同 步 锁, 执 行 同 步 块 里 的 代 码 时, 其 他 的 线 程 因 为 没 有 拥 有 这 把 锁, 就 不 能 执 行 同 步 块 里 的 代 码 即 使 该 线 程 睡 眠 了, 其 他 线 程 也 是 不 能 执 行 同 步 块 里 的 代 码 直 到 该 线 程 执 行 完 同 步 块 释 放 了 o 的 同 步 锁, 其 他 线 程 才 有 机 会 执 行 同 步 块 里 的 代 码 当 前 对 象 也 可 以 作 为 同 步 锁 使 用, 所 以 也 可 以 这 样 写 同 步 块 : synchronized(this){ 当 一 个 线 程 开 始 执 行 同 步 代 码 块 时, 并 不 意 味 着 以 不 中 断 的 方 式 运 行 进 入 同 步 代 码 的 线 程 也 可 以 执 行 Thread.sleep() 或 者 执 行 Thread.yield() 方 法, 此 时 它 并 没 有 释 放 锁, 只 是 把 运 行 机 会 让 给 了 其 他 的 线 程 同 步 方 法 功 能 使 用 synchronized 关 键 字 修 饰 的 方 法 为 同 步 方 法, 同 步 方 法 和 同 步 块 一 样 有 线 程 同 步 的 class TicketSell implements Runnable{ // 有 100 张 票 int count=100; // 同 步 锁 Object o=new Object(); 第 287 页

288 public void run(){ while(true){ if(count<1){ break; sale(); public synchronized void sale(){ if(count>0){ try{ Thread.sleep(10); catch(exception e){ System.out.println(Thread.currentThread().getName()+"="+count); count--; 同 步 方 法 中 使 用 当 前 对 象 this 作 为 同 步 锁, 所 以 不 需 要 额 外 声 明 同 步 锁 synchronized 声 明 不 会 被 继 承 如 果 一 个 用 synchronized 修 饰 的 方 法 被 子 类 覆 盖, 那 么 子 类 中 这 个 方 法 不 再 保 持 同 步, 除 非 也 用 synchronized 修 饰 同 步 与 并 发 同 步 是 解 决 共 享 资 源 竞 争 的 有 效 手 段 当 一 个 线 程 已 经 在 操 纵 共 享 资 源 时, 其 他 线 程 只 能 等 待, 只 有 当 已 经 在 操 纵 共 享 资 源 的 线 程 执 行 同 步 代 码 后, 其 他 线 程 才 有 机 会 操 纵 共 享 资 源 但 是, 多 线 程 的 同 步 与 并 发 是 一 对 此 消 彼 长 的 矛 盾 假 想 有 10 个 人 同 到 一 口 井 里 打 水, 每 个 人 都 要 打 10 桶 水, 人 代 表 线 程, 井 代 表 共 享 资 源 一 种 同 步 方 法 是 : 所 有 的 人 依 次 打 水, 只 用 当 前 一 个 人 打 完 10 桶 水 后, 其 他 人 才 有 机 会 打 水 当 一 个 人 在 打 水 期 间, 其 他 人 必 须 等 待 轮 到 最 后 一 个 打 水 的 人 肯 定 怨 声 载 道, 因 为 他 必 须 等 到 前 面 9 个 人 打 完 90 桶 水 后 才 能 打 水 为 了 提 高 并 发 性 能, 应 该 使 同 步 代 码 块 中 包 含 尽 可 能 少 的 操 作, 使 得 一 个 线 程 能 尽 快 释 放 锁, 减 少 其 他 线 程 等 待 锁 的 时 间 可 以 改 为 一 个 人 打 完 一 桶 水 后, 就 让 其 他 人 打 水, 大 家 轮 流 打 水, 直 到 每 个 人 都 打 完 10 桶 水 线 程 安 全 的 类 一 个 线 程 安 全 的 类 满 足 以 下 条 件 : 这 个 类 的 对 象 可 以 同 时 被 多 个 线 程 安 全 的 访 问 第 288 页

289 每 个 线 程 都 能 正 常 执 行 原 子 操 作, 得 到 正 确 的 结 果 在 每 个 线 程 的 原 子 操 作 都 完 成 后, 对 象 处 于 逻 辑 上 合 理 的 状 态 12.9 学 习 目 标 1. 掌 握 在 Java 中 创 建 线 程 的 两 种 方 式 ( 写 出 代 码 ) 2. 掌 握 线 程 状 态 转 移 的 结 构 3. 掌 握 线 程 调 度 的 方 法 4. 理 解 线 程 的 同 步 ( 为 什 么 需 要 线 程 的 同 步 ), 会 写 同 步 块 和 同 步 方 法 第 289 页

290 12.10 作 业 1. ( 选 择 题 ) 下 面 说 法 中 错 误 的 一 项 是 ( ) A. 线 程 就 是 程 序 B. 线 程 是 一 个 程 序 的 单 个 执 行 流 C. 多 想 成 用 于 实 现 并 发 D. 多 线 程 是 指 一 个 程 序 的 多 个 执 行 流 2. 下 列 哪 些 方 法 可 以 使 线 程 从 运 行 状 态 进 入 阻 塞 状 态 ( ) A. sleep B. wait C. yield D.start 3. 下 列 说 法 中 错 误 的 两 项 是 ( ) A. 一 个 线 程 是 一 个 Thread 类 的 实 例 B. 线 程 从 调 用 实 现 Runnable 接 口 的 实 例 的 run() 方 法 开 始 执 行 C. 新 建 的 线 程 调 用 start() 方 法 就 能 立 即 进 入 运 行 状 态 D. 在 Java 中, 高 优 先 级 的 可 运 行 线 程 会 抢 占 低 优 先 级 线 程 4. 下 列 关 于 Thread 类 提 供 的 线 程 控 制 方 法 的 说 法 中, 错 误 的 一 项 是 ( ) A. 在 线 程 A 中 执 行 线 程 B 的 join() 方 法, 则 线 程 A 等 待 直 到 B 执 行 完 成 B. 线 程 A 通 过 调 用 interrupt() 方 法 来 中 断 其 阻 塞 状 态 C. 若 线 程 A 调 用 方 法 isalive() 返 回 值 为 true, 则 说 明 A 正 在 执 行 中 D. currentthread() 方 法 返 回 当 前 线 程 的 引 用 5. 下 列 说 法 中, 错 误 的 一 项 是 ( ) A. 对 象 锁 在 synchronized 块 执 行 完 成 之 后 由 持 有 它 的 线 程 返 还 B. 对 象 锁 在 synchronized 块 中 出 现 异 常 时 有 持 有 它 的 线 程 返 还 C. 当 持 有 锁 的 线 程 调 用 了 该 对 象 的 wait() 方 法 时, 线 程 将 释 放 其 持 有 的 锁 D. 当 持 有 锁 的 线 程 调 用 了 该 对 象 的 构 造 方 法 时, 线 程 将 释 放 其 持 有 的 锁 6. 编 写 一 个 用 线 程 实 现 一 个 数 字 时 钟 的 应 用 程 序 该 线 程 类 要 采 用 休 眠 的 方 式, 把 绝 对 大 部 分 时 间 让 系 统 使 用 7. 创 建 一 个 线 程, 指 定 一 个 限 定 时 间 ( 如 60s), 线 程 运 行 时, 大 约 每 3s 输 出 1 次 当 前 所 剩 时 间, 直 至 给 定 的 限 定 时 间 用 完 (sleep 方 法 ) 8. 编 写 一 个 多 线 程 程 序, 其 中 一 个 线 程 完 成 对 某 个 对 象 的 int 成 员 变 量 的 增 加 操 作, 即 每 次 加 1, 另 一 个 线 程 完 成 对 该 对 象 的 成 员 变 量 的 减 操 作, 即 每 次 减 1, 同 时 要 保 证 该 变 量 的 值 不 会 小 于 0, 不 会 大 于 10, 该 变 量 的 初 始 值 为 0 第 290 页

291 13 网 络 编 程 13.1 基 本 概 念 计 算 机 网 络 计 算 机 网 络 是 相 互 连 接 的 独 立 自 主 的 计 算 机 集 合 最 简 单 的 网 络 形 式 是 由 两 台 计 算 机 组 成 的 ISO/OSI 七 层 参 考 模 型 OSI(Open System Interconnection) 参 考 模 型 将 网 络 的 不 同 功 能 划 分 为 7 层 : 第 291 页

292 通 信 实 体 的 对 等 层 之 间 不 允 许 直 接 通 信 各 层 之 间 是 严 格 的 单 向 依 赖 关 系 上 层 使 用 下 层 提 供 的 服 务 ----Service user 下 层 向 上 层 提 供 服 务 ----Service provider OSI 各 层 所 使 用 的 协 议 : 应 用 层 : 远 程 登 录 协 议 Telnet 文 件 传 输 协 议 FTP 超 文 本 传 输 协 议 HTTP 域 名 服 务 DNS 简 单 邮 件 传 输 协 议 SMTP 邮 局 协 议 POP3 等 传 输 层 : 传 输 控 制 协 议 TCP 用 户 数 据 报 协 议 UDP TCP: 面 向 连 接 的 可 靠 的 传 输 协 议 UDP: 是 无 连 接 的, 不 可 靠 地 传 输 协 议 网 络 层 : 网 际 协 议 IP Internet 互 联 网 控 制 报 文 协 议 ICMP Internet 组 管 理 协 议 IGMP IP 地 址 IP 网 络 中 每 台 主 机 都 必 须 有 一 个 唯 一 的 网 络 地 址 IP 地 址 是 一 个 逻 辑 地 址 英 特 网 上 的 IP 地 址 具 有 全 球 唯 一 性 第 292 页

《C语言基础入门》课程教学大纲

《C语言基础入门》课程教学大纲 C 语 言 开 发 入 门 教 程 课 程 教 学 大 纲 课 程 编 号 :201409210011 学 分 :5 学 分 学 时 :58 学 时 ( 其 中 : 讲 课 学 时 :39 学 时 上 机 学 时 :19 学 时 ) 先 修 课 程 : 计 算 机 导 论 后 续 课 程 :C++ 程 序 设 计 适 用 专 业 : 信 息 及 其 计 算 机 相 关 专 业 开 课 部 门 : 计

More information

说 明 为 了 反 映 教 运 行 的 基 本 状 态, 为 校 和 院 制 定 相 关 政 策 和 进 行 教 建 设 与 改 革 提 供 据 依 据, 校 从 程 资 源 ( 开 类 别 开 量 规 模 ) 教 师 结 构 程 考 核 等 维 度, 对 2015 年 春 季 期 教 运 行 基

说 明 为 了 反 映 教 运 行 的 基 本 状 态, 为 校 和 院 制 定 相 关 政 策 和 进 行 教 建 设 与 改 革 提 供 据 依 据, 校 从 程 资 源 ( 开 类 别 开 量 规 模 ) 教 师 结 构 程 考 核 等 维 度, 对 2015 年 春 季 期 教 运 行 基 内 部 资 料 东 北 师 范 大 教 运 行 基 本 状 态 据 报 告 2015 年 春 季 期 教 务 处 2015 年 10 月 27 日 说 明 为 了 反 映 教 运 行 的 基 本 状 态, 为 校 和 院 制 定 相 关 政 策 和 进 行 教 建 设 与 改 革 提 供 据 依 据, 校 从 程 资 源 ( 开 类 别 开 量 规 模 ) 教 师 结 构 程 考 核 等 维 度,

More information

何 秋 琳 张 立 春 视 觉 学 习 研 究 进 展 视 觉 注 意 视 觉 感 知

何 秋 琳 张 立 春 视 觉 学 习 研 究 进 展 视 觉 注 意 视 觉 感 知 第 卷 第 期 年 月 开 放 教 育 研 究 何 秋 琳 张 立 春 华 南 师 范 大 学 未 来 教 育 研 究 中 心 广 东 广 州 随 着 图 像 化 技 术 和 电 子 媒 体 的 发 展 视 觉 学 习 也 逐 步 发 展 为 学 习 科 学 的 一 个 研 究 分 支 得 到 研 究 人 员 和 教 育 工 作 者 的 广 泛 关 注 基 于 此 作 者 试 图 对 视 觉 学 习

More information

评 委 : 李 炎 斌 - 个 人 技 术 标 资 信 标 初 步 审 查 明 细 表 序 号 投 标 单 位 投 标 函 未 按 招 标 文 件 规 定 填 写 漏 填 或 内 容 填 写 错 误 的 ; 不 同 投 标 人 的 投 标 文 件 由 同 一 台 电 脑 或 同 一 家 投 标 单

评 委 : 李 炎 斌 - 个 人 技 术 标 资 信 标 初 步 审 查 明 细 表 序 号 投 标 单 位 投 标 函 未 按 招 标 文 件 规 定 填 写 漏 填 或 内 容 填 写 错 误 的 ; 不 同 投 标 人 的 投 标 文 件 由 同 一 台 电 脑 或 同 一 家 投 标 单 评 委 : 李 炎 斌 - 个 人 清 标 评 审 明 细 表 评 审 因 素 序 号 投 标 单 位 清 标 评 审 1 深 圳 市 创 捷 科 技 有 限 合 格 2 四 川 川 大 智 胜 软 件 股 份 有 限 合 格 3 北 京 航 天 长 峰 科 技 工 业 集 团 有 限 公 司 合 格 4 深 圳 中 兴 力 维 技 术 有 限 合 格 5 深 圳 键 桥 通 讯 技 术 股 份 有

More information

I

I 机 电 一 级 注 册 建 造 师 继 续 教 育 培 训 广 东 培 训 点 网 上 报 名 操 作 使 用 手 册 (2013 年 1 月, 第 一 版 ) 第 一 章 个 人 注 册 与 个 人 信 息 管 理 1. 个 人 注 册 ( 请 每 人 只 申 请 一 个 注 册 号, 如 果 单 位 批 量 报 班 单 位 帮 申 请 注 册, 不 需 个 人 再 注 册 ) 首 次 报 班,

More information

,,,,, :,, (.,, );, (, : ), (.., ;. &., ;.. &.., ;, ;, ),,,,,,, ( ) ( ),,,,.,,,,,, : ;, ;,.,,,,, (., : - ),,,, ( ),,,, (, : ),, :,

,,,,, :,, (.,, );, (, : ), (.., ;. &., ;.. &.., ;, ;, ),,,,,,, ( ) ( ),,,,.,,,,,, : ;, ;,.,,,,, (., : - ),,,, ( ),,,, (, : ),, :, : 周 晓 虹 : - -., - - - -. :( ), -,.( ),,, -. - ( ).( ) ', -,,,,, ( ).( ),,, -., '.,, :,,,, :,,,, ,,,,, :,, (.,, );, (, : ), (.., ;. &., ;.. &.., ;, ;, ),,,,,,, ( ) ( ),,,,.,,,,,, : ;, ;,.,,,,, (., : - ),,,,

More information

Microsoft Word - 第7章 图表反转形态.doc

Microsoft Word - 第7章 图表反转形态.doc 第 七 章 图 表 反 转 形 态 我 们 知 道 市 场 趋 势 共 有 三 种 : 上 升 趋 势 下 降 趋 势 和 横 向 整 理 市 场 的 价 格 波 动 都 是 运 行 在 这 三 种 趋 势 中, 所 有 的 走 势 都 是 这 三 种 趋 势 的 排 列 组 合 如 图 市 场 趋 势 结 构 示 意 图 7-1 所 示 市 场 趋 势 结 构 示 意 图 7-1 图 市 场 趋

More information

<433A5C446F63756D656E747320616E642053657474696E67735C41646D696E6973747261746F725CD7C0C3E65CC2DBCEC4CFB5CDB3CAB9D3C3D6B8C4CFA3A8BCF2BBAFA3A95CCAB9D3C3D6B8C4CF31302D31392E646F63>

<433A5C446F63756D656E747320616E642053657474696E67735C41646D696E6973747261746F725CD7C0C3E65CC2DBCEC4CFB5CDB3CAB9D3C3D6B8C4CFA3A8BCF2BBAFA3A95CCAB9D3C3D6B8C4CF31302D31392E646F63> ( 一 ) 系 统 整 体 操 作 流 程 简 述 3 ( 二 ) 系 统 中 各 角 色 操 作 功 能 说 明 5 1. 学 院 管 理 员 5 2. 教 学 院 长 8 3. 指 导 教 师 10 4. 答 辩 组 组 长 12 5. 学 生 12 6. 系 统 管 理 员 15 ( 一 ) 论 文 系 统 常 见 问 题 16 ( 二 ) 论 文 查 重 常 见 问 题 22 1 2 主

More information

(2015-2016-2)-0004186-04205-1 140242 信 号 与 系 统 Ⅰ 学 科 基 础 必 修 课 37 37 1 教 203 17 周 2016 年 06 月 13 日 (08:00-09:35) (2015-2016-2)-0004186-04205-1 141011

(2015-2016-2)-0004186-04205-1 140242 信 号 与 系 统 Ⅰ 学 科 基 础 必 修 课 37 37 1 教 203 17 周 2016 年 06 月 13 日 (08:00-09:35) (2015-2016-2)-0004186-04205-1 141011 关 于 2015-2016 学 年 第 二 学 期 期 末 周 内 考 试 时 间 地 点 安 排 选 课 课 号 班 级 名 称 课 程 名 称 课 程 性 质 合 考 人 数 实 际 人 数 考 试 教 室 考 试 段 考 试 时 间 (2015-2016-2)-0006178-04247-1 130101 测 试 技 术 基 础 学 科 基 础 必 修 课 35 35 1 教 401 17 周

More information

修改版-操作手册.doc

修改版-操作手册.doc 职 称 信 息 系 统 升 级 指 南 须 使 用 IE9 及 其 以 上 版 本 浏 览 器 或 谷 歌 浏 览 器 登 录 www.njrs.gov.cn 南 京 市 职 称 ( 职 业 资 格 ) 工 作 领 导 小 组 办 公 室 2016 年 5 月 目 录 一 申 报 人 员 操 作 指 南...1 1.1 职 称 初 定 申 报...1 1.1.1 职 称 初 定 基 础 信 息 填

More information

评 委 : 徐 岩 宇 - 个 人 技 术 标 资 信 标 初 步 审 查 明 细 表 序 号 投 标 单 位 投 标 函 未 按 招 标 文 件 规 定 填 写 漏 填 或 内 容 填 写 错 误 的 ; 不 同 投 标 人 的 投 标 文 件 由 同 一 台 电 脑 或 同 一 家 投 标 单

评 委 : 徐 岩 宇 - 个 人 技 术 标 资 信 标 初 步 审 查 明 细 表 序 号 投 标 单 位 投 标 函 未 按 招 标 文 件 规 定 填 写 漏 填 或 内 容 填 写 错 误 的 ; 不 同 投 标 人 的 投 标 文 件 由 同 一 台 电 脑 或 同 一 家 投 标 单 评 委 : 徐 岩 宇 - 个 人 清 标 评 审 明 细 表 评 审 因 素 序 号 投 标 单 位 清 标 评 审 1 深 圳 市 创 捷 科 技 有 限 合 格 2 四 川 川 大 智 胜 软 件 股 份 有 限 合 格 3 北 京 航 天 长 峰 科 技 工 业 集 团 有 限 公 司 合 格 4 深 圳 中 兴 力 维 技 术 有 限 合 格 5 深 圳 键 桥 通 讯 技 术 股 份 有

More information

龚 亚 夫 在 重 新 思 考 基 础 教 育 英 语 教 学 的 理 念 一 文 中 援 引 的 观 点 认 为 当 跳 出 本 族 语 主 义 的 思 维 定 式 后 需 要 重 新 思 考 许 多 相 连 带 的 问 题 比 如 许 多 发 音 的 细 微 区 别 并 不 影 响 理 解 和

龚 亚 夫 在 重 新 思 考 基 础 教 育 英 语 教 学 的 理 念 一 文 中 援 引 的 观 点 认 为 当 跳 出 本 族 语 主 义 的 思 维 定 式 后 需 要 重 新 思 考 许 多 相 连 带 的 问 题 比 如 许 多 发 音 的 细 微 区 别 并 不 影 响 理 解 和 语 音 语 篇 语 感 语 域 林 大 津 毛 浩 然 改 革 开 放 以 来 的 英 语 热 引 发 了 大 中 小 学 英 语 教 育 整 体 规 划 问 题 在 充 分 考 虑 地 区 学 校 和 个 体 差 异 以 及 各 家 观 点 的 基 础 上 遵 循 实 事 求 是 逐 级 定 位 逐 层 分 流 因 材 施 教 的 原 则 本 研 究 所 倡 导 的 语 音 语 篇 语 感 语 域

More information

深圳市新亚电子制程股份有限公司

深圳市新亚电子制程股份有限公司 证 券 代 码 :002388 证 券 简 称 : 新 亚 制 程 公 告 编 号 :2016-053 深 圳 市 新 亚 电 子 制 程 股 份 有 限 公 司 2016 年 第 二 次 临 时 股 东 大 会 决 议 公 告 本 公 司 及 董 事 会 全 体 成 员 保 证 公 告 内 容 真 实 准 确 和 完 整, 不 存 在 虚 假 记 载 误 导 性 陈 述 或 者 重 大 遗 漏 特

More information

18 上 报 该 学 期 新 生 数 据 至 阳 光 平 台 第 一 学 期 第 四 周 至 第 六 周 19 督 促 学 习 中 心 提 交 新 增 专 业 申 请 第 一 学 期 第 四 周 至 第 八 周 20 编 制 全 国 网 络 统 考 十 二 月 批 次 考 前 模 拟 题 第 一 学

18 上 报 该 学 期 新 生 数 据 至 阳 光 平 台 第 一 学 期 第 四 周 至 第 六 周 19 督 促 学 习 中 心 提 交 新 增 专 业 申 请 第 一 学 期 第 四 周 至 第 八 周 20 编 制 全 国 网 络 统 考 十 二 月 批 次 考 前 模 拟 题 第 一 学 1 安 排 组 织 全 国 网 络 统 考 九 月 批 次 网 上 考 前 辅 导 第 一 学 期 第 一 周 统 考 考 前 半 个 月 2 下 发 全 国 网 络 统 考 九 月 批 次 准 考 证 第 一 学 期 第 一 周 导 出 下 半 年 成 人 本 科 学 士 学 位 英 语 统 一 考 试 报 考 3 信 息 第 一 学 期 第 一 周 4 教 学 计 划 和 考 试 计 划 上 网,

More information

HSK( 一 级 ) 考 查 考 生 的 日 常 汉 语 应 用 能 力, 它 对 应 于 国 际 汉 语 能 力 标 准 一 级 欧 洲 语 言 共 同 参 考 框 架 (CEF) A1 级 通 过 HSK( 一 级 ) 的 考 生 可 以 理 解 并 使 用 一 些 非 常 简 单 的 汉 语

HSK( 一 级 ) 考 查 考 生 的 日 常 汉 语 应 用 能 力, 它 对 应 于 国 际 汉 语 能 力 标 准 一 级 欧 洲 语 言 共 同 参 考 框 架 (CEF) A1 级 通 过 HSK( 一 级 ) 的 考 生 可 以 理 解 并 使 用 一 些 非 常 简 单 的 汉 语 新 汉 语 水 平 考 试 HSK 为 使 汉 语 水 平 考 试 (HSK) 更 好 地 服 务 于 汉 语 学 习 者, 中 国 国 家 汉 办 组 织 中 外 汉 语 教 学 语 言 学 心 理 学 和 教 育 测 量 学 等 领 域 的 专 家, 在 充 分 调 查 了 解 海 外 实 际 汉 语 教 学 情 况 的 基 础 上, 吸 收 原 有 HSK 的 优 点, 借 鉴 近 年 来 国

More information

文 化 记 忆 传 统 创 新 与 节 日 遗 产 保 护 根 据 德 国 学 者 阿 斯 曼 的 文 化 记 忆 理 论 仪 式 与 文 本 是 承 载 文 化 记 忆 的 两 大 媒 体 在 各 种 仪 式 行 为 中 节 日 以 其 高 度 的 公 共 性 有 组 织 性 和 历 史 性 而 特 别 适 用 于 文 化 记 忆 的 储 存 和 交 流 节 日 的 文 化 功 能 不 仅 在 于

More information

一 公 共 卫 生 硕 士 专 业 学 位 论 文 的 概 述 学 位 论 文 是 对 研 究 生 进 行 科 学 研 究 或 承 担 专 门 技 术 工 作 的 全 面 训 练, 是 培 养 研 究 生 创 新 能 力, 综 合 运 用 所 学 知 识 发 现 问 题, 分 析 问 题 和 解 决

一 公 共 卫 生 硕 士 专 业 学 位 论 文 的 概 述 学 位 论 文 是 对 研 究 生 进 行 科 学 研 究 或 承 担 专 门 技 术 工 作 的 全 面 训 练, 是 培 养 研 究 生 创 新 能 力, 综 合 运 用 所 学 知 识 发 现 问 题, 分 析 问 题 和 解 决 上 海 市 公 共 卫 生 硕 士 专 业 学 位 论 文 基 本 要 求 和 评 价 指 标 体 系 ( 试 行 ) 上 海 市 学 位 委 员 会 办 公 室 二 O 一 二 年 三 月 一 公 共 卫 生 硕 士 专 业 学 位 论 文 的 概 述 学 位 论 文 是 对 研 究 生 进 行 科 学 研 究 或 承 担 专 门 技 术 工 作 的 全 面 训 练, 是 培 养 研 究 生 创

More information

Microsoft Word - 文件汇编.doc

Microsoft Word - 文件汇编.doc 北 京 市 中 医 管 理 局 二 一 五 年 四 月 ... 1... 18 2015... 30 京 中 医 政 字 [2014]160 号 1 2 一 充 分 认 识 中 医 健 康 乡 村 建 设 工 作 的 重 要 意 义 二 建 立 健 全 工 作 保 障 机 制 2014 12 15 三 做 好 工 作 启 动 的 准 备 事 宜 1 2014 12 15 5-10 2014 12 15

More information

国债回购交易业务指引

国债回购交易业务指引 附 件 1 上 海 证 券 交 易 所 新 质 押 式 国 债 回 购 交 易 业 务 指 引 一 总 述 根 据 上 海 证 券 交 易 所 债 券 交 易 实 施 细 则, 上 证 所 将 于 2006 年 5 月 8 日 起 推 出 新 质 押 式 国 债 回 购 新 质 押 式 回 购 与 现 行 质 押 式 回 购 相 比 区 别 主 要 在 以 下 几 个 方 面 :1 新 质 押 式

More information

ETF、分级基金规模、份额变化统计20130816

ETF、分级基金规模、份额变化统计20130816 ETF 分 级 基 金 规 模 份 额 变 化 统 计 截 至 上 周 末, 全 市 场 股 票 型 ETF 规 模 约 1451 亿, 份 额 约 1215 亿,ETF 总 份 额 及 规 模 的 周 变 动 值 分 别 为 -23-44 亿, 份 额 与 规 模 均 下 降 ; 分 级 基 金 规 模 约 438 亿, 份 额 572 亿, 总 份 额 及 规 模 的 周 变 动 值 分 别 为

More information

第2章 数据类型、常量与变量

第2章  数据类型、常量与变量 第 2 章 数 据 类 型 常 量 与 变 量 在 计 算 机 程 序 中 都 是 通 过 值 (value) 来 进 行 运 算 的, 能 够 表 示 并 操 作 值 的 类 型 为 数 据 类 型 在 本 章 里 将 会 介 绍 JavaScript 中 的 常 量 (literal) 变 量 (variable) 和 数 据 类 型 (data type) 2.1 基 本 数 据 类 型 JavaScript

More information

2 熟 悉 Visual Basic 的 集 成 开 发 环 境 3 了 解 可 视 化 面 向 对 象 编 程 事 件 驱 动 交 互 式 开 发 等 基 本 概 念 4 了 解 Visual Basic 的 特 点 环 境 要 求 与 安 装 方 法 1 Visual Basic 开 发 应 用

2 熟 悉 Visual Basic 的 集 成 开 发 环 境 3 了 解 可 视 化 面 向 对 象 编 程 事 件 驱 动 交 互 式 开 发 等 基 本 概 念 4 了 解 Visual Basic 的 特 点 环 境 要 求 与 安 装 方 法 1 Visual Basic 开 发 应 用 Visual Basic 程 序 设 计 A 级 分 级 班 教 学 大 纲 ( 供 计 算 机 与 信 息 技 术 基 础 课 程 分 级 教 学 A 级 班 使 用 ) I 前 言 Visual Basic 程 序 设 计 课 程 是 一 门 计 算 机 语 言 基 础 课 程 通 过 对 该 课 程 的 学 习, 使 学 生 初 步 掌 握 Visual Basic 的 语 言 特 点, 掌

More information

珠江钢琴股东大会

珠江钢琴股东大会 证 券 代 码 :002678 证 券 简 称 : 珠 江 钢 琴 公 告 编 号 :2015-038 广 州 珠 江 钢 琴 集 团 股 份 有 限 公 司 2015 年 年 度 股 东 大 会 决 议 公 告 本 公 司 及 董 事 会 全 体 成 员 保 证 信 息 披 露 的 内 容 真 实 准 确 完 整, 没 有 虚 假 记 载 误 导 性 陈 述 或 重 大 遗 漏 特 别 提 示 :

More information

Microsoft Word - 第3章.doc

Microsoft Word - 第3章.doc 52 5 天 通 过 职 称 计 算 机 考 试 ( 考 点 视 频 串 讲 + 全 真 模 拟 ) Word 2003 中 文 字 处 理 ( 第 2 版 ) 第 3 章 3 字 符 格 式 需 要 掌 握 的 考 点 字 体 字 形 和 字 号 的 设 置 ; 上 标 下 标 空 心 字 等 字 体 效 果 的 使 用 ; 字 符 间 距 的 调 整 ; 改 变 字 符 颜 色 底 纹 添 加

More information

马 克 思 主 义 公 正 观 的 基 本 向 度 及 方 法 论 原 则!! # #

马 克 思 主 义 公 正 观 的 基 本 向 度 及 方 法 论 原 则!! # # 马 克 思 主 义 公 正 观 的 基 本 向 度 及 方 法 论 原 则 马 俊 峰 在 社 会 公 正 问 题 的 大 讨 论 中 罗 尔 斯 诺 齐 克 哈 耶 克 麦 金 泰 尔 等 当 代 西 方 思 想 家 的 论 述 被 反 复 引 用 和 申 说 而 将 马 克 思 恩 格 斯 等 经 典 作 家 的 观 点 置 于 一 种 被 忽 视 甚 至 被 忘 却 的 状 态 形 成 这 种

More information

金 不 少 于 800 万 元, 净 资 产 不 少 于 960 万 元 ; (3) 近 五 年 独 立 承 担 过 单 项 合 同 额 不 少 于 1000 万 元 的 智 能 化 工 程 ( 设 计 或 施 工 或 设 计 施 工 一 体 ) 不 少 于 2 项 ; (4) 近 三 年 每 年

金 不 少 于 800 万 元, 净 资 产 不 少 于 960 万 元 ; (3) 近 五 年 独 立 承 担 过 单 项 合 同 额 不 少 于 1000 万 元 的 智 能 化 工 程 ( 设 计 或 施 工 或 设 计 施 工 一 体 ) 不 少 于 2 项 ; (4) 近 三 年 每 年 工 程 设 计 与 施 工 资 质 标 准 一 总 则 建 筑 智 能 化 工 程 设 计 与 施 工 资 质 标 准 ( 一 ) 为 了 加 强 对 从 事 建 筑 智 能 化 工 程 设 计 与 施 工 企 业 的 管 理, 维 护 建 筑 市 场 秩 序, 保 证 工 程 质 量 和 安 全, 促 进 行 业 健 康 发 展, 结 合 建 筑 智 能 化 工 程 的 特 点, 制 定 本 标

More information

抗 战 时 期 国 民 政 府 的 银 行 监 理 体 制 探 析 % # % % % ) % % # # + #, ) +, % % % % % % % %

抗 战 时 期 国 民 政 府 的 银 行 监 理 体 制 探 析 % # % % % ) % % # # + #, ) +, % % % % % % % % 抗 战 时 期 国 民 政 府 的 银 行 监 理 体 制 探 析 王 红 曼 抗 战 时 期 国 民 政 府 为 适 应 战 时 经 济 金 融 的 需 要 实 行 由 财 政 部 四 联 总 处 中 央 银 行 等 多 家 机 构 先 后 共 同 参 与 的 多 元 化 银 行 监 理 体 制 对 战 时 状 态 下 的 银 行 发 展 与 经 营 安 全 进 行 了 大 规 模 的 设 计 与

More information

2006年顺德区高中阶段学校招生录取分数线

2006年顺德区高中阶段学校招生录取分数线 2014 年 顺 德 区 高 中 阶 段 学 校 考 试 提 前 批 第 一 批 第 二 批 学 校 录 取 根 据 佛 山 市 办 提 供 的 考 生 数 据, 现 将 我 区 2014 年 高 中 阶 段 学 校 考 试 提 前 批 第 一 批 第 二 批 学 校 的 录 取 公 布 如 下 : 一 顺 德 一 中 录 取 分 第 1 志 愿, 总 分 585, 综 合 表 现 评 价 A, 考

More information

 编号:

 编号: 编 号 : 企 业 内 高 技 能 人 才 培 养 评 价 实 施 方 案 ( 仅 适 用 于 企 业 特 有 行 业 特 有 工 种 ) 实 施 单 位 ( 公 章 ) 申 报 日 期 年 _ 月 日 1 企 业 内 高 技 能 人 才 培 养 评 价 项 目 实 施 方 案 申 报 表 项 目 名 称 等 级 项 目 性 质 课 时 申 报 单 位 联 系 人 通 讯 地 址 电 话 手 机 电

More information

登录、注册功能的测试用例设计.doc

登录、注册功能的测试用例设计.doc 注 册 登 陆 测 试 用 例 和 修 改 密 码 测 试 用 例 完 整 版 摘 自 网 络, 狗 狗 整 理 zqh139@126.com 修 改 历 史 日 期 版 本 作 者 修 改 内 容 评 审 号 变 更 控 制 号 2010-11-25 1.0 初 稿 2011-09-17 2.0 整 理 一 注 册 测 试 用 例 序 号 : 1 控 件 名 称 : 功 能 描 述 : 注 册 编

More information

张 荣 芳 中 山 大 学 历 史 系 广 东 广 州 张 荣 芳 男 广 东 廉 江 人 中 山 大 学 历 史 系 教 授 博 士 生 导 师 我 们 要 打 破 以 前 学 术 界 上 的 一 切 偶 像 以 前 学 术 界 的 一 切 成 见 屏 除 我 们 要 实 地 搜 罗 材 料 到 民 众 中 寻 方 言 到 古 文 化 的 遗 址 去 发 掘 到 各 种 的 人 间 社 会 去

More information

<4D F736F F D D323630D6D0B9FAD3A6B6D4C6F8BAF2B1E4BBAFB5C4D5FEB2DFD3EBD0D0B6AF C4EAB6C8B1A8B8E6>

<4D F736F F D D323630D6D0B9FAD3A6B6D4C6F8BAF2B1E4BBAFB5C4D5FEB2DFD3EBD0D0B6AF C4EAB6C8B1A8B8E6> 中 国 应 对 气 候 变 化 的 政 策 与 行 动 2013 年 度 报 告 国 家 发 展 和 改 革 委 员 会 二 〇 一 三 年 十 一 月 100% 再 生 纸 资 源 目 录 前 言... 1 一 应 对 气 候 变 化 面 临 的 形 势... 3 二 完 善 顶 层 设 计 和 体 制 机 制... 4 三 减 缓 气 候 变 化... 8 四 适 应 气 候 变 化... 20

More information

目 录 一 系 统 访 问... 1 二 门 户 首 页 申 报 用 户 审 核 用 户... 2 三 系 统 登 录 用 户 名 密 码 登 录 新 用 户 注 册 用 户 登 录 已 注 册 用

目 录 一 系 统 访 问... 1 二 门 户 首 页 申 报 用 户 审 核 用 户... 2 三 系 统 登 录 用 户 名 密 码 登 录 新 用 户 注 册 用 户 登 录 已 注 册 用 水 路 运 输 建 设 综 合 管 理 信 息 系 统 - 门 户 系 统 用 户 手 册 二 零 一 五 年 十 一 月 目 录 一 系 统 访 问... 1 二 门 户 首 页... 1 1. 申 报 用 户... 1 2. 审 核 用 户... 2 三 系 统 登 录... 4 1. 用 户 名 密 码 登 录... 4 1.1 新 用 户 注 册... 4 1.2 用 户 登 录... 7

More information

目 录 关 于 图 标... 3 登 陆 主 界 面... 3 工 单 管 理... 5 工 单 列 表... 5 搜 索 工 单... 5 工 单 详 情... 6 创 建 工 单... 9 设 备 管 理 巡 检 计 划 查 询 详 情 销 售 管

目 录 关 于 图 标... 3 登 陆 主 界 面... 3 工 单 管 理... 5 工 单 列 表... 5 搜 索 工 单... 5 工 单 详 情... 6 创 建 工 单... 9 设 备 管 理 巡 检 计 划 查 询 详 情 销 售 管 宝 汇 德 Turbocare 微 服 务 系 统 客 户 操 作 手 册 Version 2.0 北 京 宝 汇 德 技 术 服 务 器 有 限 公 司 技 术 研 发 部 目 录 关 于 图 标... 3 登 陆 主 界 面... 3 工 单 管 理... 5 工 单 列 表... 5 搜 索 工 单... 5 工 单 详 情... 6 创 建 工 单... 9 设 备 管 理... 10 巡

More information

<4D6963726F736F667420576F7264202D20B9D8D3DAB0BABBAAA3A8C9CFBAA3A3A9D7D4B6AFBBAFB9A4B3CCB9C9B7DDD3D0CFDEB9ABCBBE32303132C4EAC4EAB6C8B9C9B6ABB4F3BBE1B7A8C2C9D2E2BCFBCAE92E646F6378>

<4D6963726F736F667420576F7264202D20B9D8D3DAB0BABBAAA3A8C9CFBAA3A3A9D7D4B6AFBBAFB9A4B3CCB9C9B7DDD3D0CFDEB9ABCBBE32303132C4EAC4EAB6C8B9C9B6ABB4F3BBE1B7A8C2C9D2E2BCFBCAE92E646F6378> 上 海 德 载 中 怡 律 师 事 务 所 关 于 昂 华 ( 上 海 ) 自 动 化 工 程 股 份 有 限 公 司 二 〇 一 二 年 年 度 股 东 大 会 法 律 意 见 书 上 海 德 载 中 怡 律 师 事 务 所 上 海 市 银 城 中 路 168 号 上 海 银 行 大 厦 1705 室 (200120) 电 话 :8621-5012 2258 传 真 :8621-5012 2257

More information

2014年中央财经大学研究生招生录取工作简报

2014年中央财经大学研究生招生录取工作简报 2015 年 中 央 财 经 大 学 研 究 生 招 生 录 取 工 作 简 报 一 硕 士 研 究 生 招 生 录 取 情 况 2015 年 共 有 8705 人 报 考 我 校 硕 士 研 究 生, 其 中 学 术 型 研 究 生 报 考 3657 人, 专 业 硕 士 研 究 生 报 考 5048 人 ; 总 报 考 人 数 较 2014 年 增 长 1.4%, 学 术 型 报 考 人 数 较

More information

科 学 出 版 社 科 学 出 版 社 前 言 本 书 是 针 对 普 通 高 等 院 校 经 济 类 和 工 商 管 理 类 本 科 专 业 财 务 管 理 学 的 教 学 需 求, 结 合 教 育 部 经 济 管 理 类 本 科 财 务 管 理 学 课 程 教 学 大 纲 编 写 而 成 的 本 书 执 笔 者 都 是 长 期 工 作 在 财 务 管 理 教 学 一 线 的 专 业 教 师,

More information

1600 1000 40 50 2030 2000 采 取 行 动 的 机 会 90% 开 拓 成 功 的 道 路 2

1600 1000 40 50 2030 2000 采 取 行 动 的 机 会 90% 开 拓 成 功 的 道 路 2 简 略 版 本 :2015 3 10 2016 2021 全 球 卫 生 部 门 病 毒 性 肝 炎 战 略 2016 2021 2015 3 12 2012 2010 2014 2015 2016 2021 140 55% 35% 5 15% 5 20% 2.4 1.3 1.5 1 1600 1000 40 50 2030 2000 采 取 行 动 的 机 会 90% 开 拓 成 功 的 道 路

More information

世华财讯模拟操作手册

世华财讯模拟操作手册 第 一 部 分 : 股 票 模 拟 操 作 部 分 1. 登 录 与 主 界 面 1.1 登 录 学 生 在 桌 面 上, 打 开 世 华 文 件 夹, 直 接 双 击 文 件 夹 中 的 快 捷 图 标, 系 统 弹 出 世 华 财 讯 模 拟 股 票 交 易 系 统 ( 客 户 端 ) 窗 口, 如 图 1.1 所 示 图 1.1 请 输 入 登 录 名 称 及 密 码, 单 击 确 认 登 录

More information

中 国 软 科 学 年 第 期!!!

中 国 软 科 学 年 第 期!!! 山 寨 模 式 的 形 成 机 理 及 其 对 组 织 创 新 的 启 示 山 寨 模 式 的 形 成 机 理 及 其 对 组 织 创 新 的 启 示 陶 厚 永 李 燕 萍 骆 振 心 武 汉 大 学 经 济 与 管 理 学 院 武 汉 大 学 中 国 产 学 研 合 作 问 题 研 究 中 心 湖 北 武 汉 北 京 大 学 经 济 研 究 所 光 华 天 成 博 士 后 工 作 站 北 京 本

More information

证券代码:000066 证券简称:长城电脑 公告编号:2014-000

证券代码:000066         证券简称:长城电脑        公告编号:2014-000 证 券 代 码 :000066 证 券 简 称 : 长 城 电 脑 公 告 编 号 :2016-092 中 国 长 城 计 算 机 深 圳 股 份 有 限 公 司 2016 年 度 第 三 次 临 时 股 东 大 会 决 议 公 告 本 公 司 及 其 董 事 会 全 体 成 员 保 证 信 息 披 露 内 容 的 真 实 准 确 完 整, 没 有 虚 假 记 载 误 导 性 陈 述 或 重 大 遗

More information

0 年 上 半 年 评 价 与 考 核 细 则 序 号 部 门 要 素 值 考 核 内 容 考 核 方 式 考 核 标 准 考 核 ( 扣 原 因 ) 考 评 得 3 安 全 生 产 目 30 无 同 等 责 任 以 上 道 路 交 通 亡 人 事 故 无 轻 伤 责 任 事 故 无 重 大 质 量

0 年 上 半 年 评 价 与 考 核 细 则 序 号 部 门 要 素 值 考 核 内 容 考 核 方 式 考 核 标 准 考 核 ( 扣 原 因 ) 考 评 得 3 安 全 生 产 目 30 无 同 等 责 任 以 上 道 路 交 通 亡 人 事 故 无 轻 伤 责 任 事 故 无 重 大 质 量 0 年 上 半 年 评 价 与 考 核 细 则 序 号 部 门 要 素 值 考 核 内 容 考 核 方 式 考 核 标 准 无 同 等 责 任 以 上 道 路 交 通 亡 人 事 故 3 无 轻 伤 责 任 事 故 目 标 30 及 事 无 重 大 质 量 工 作 过 失 故 管 无 其 他 一 般 责 任 事 故 理 在 公 司 文 明 环 境 创 建 中, 无 工 作 过 失 及 被 追 究 的

More information

中 中 中 中 部 中 岗 位 条 件 历 其 它 历 史 师 地 理 师 生 物 师 体 与 健 康 师 04 05 06 07 从 事 中 历 史 工 从 事 中 地 理 工 从 事 中 生 物 工 从 事 中 体 与 健 康 工 2. 课 程 与 论 ( 历 史 ); 2. 科 ( 历 史 )

中 中 中 中 部 中 岗 位 条 件 历 其 它 历 史 师 地 理 师 生 物 师 体 与 健 康 师 04 05 06 07 从 事 中 历 史 工 从 事 中 地 理 工 从 事 中 生 物 工 从 事 中 体 与 健 康 工 2. 课 程 与 论 ( 历 史 ); 2. 科 ( 历 史 ) 中 中 中 部 中 26 年 系 统 事 业 公 开 计 划 岗 位 条 件 历 其 它 数 师 英 语 师 物 理 师 02 0 从 事 中 数 工 从 事 中 英 语 工 从 事 中 物 理 工 2. 课 程 与 论 ( 数 ); 2. 科 ( 数 );. 数 ; 4. 基 础 数 ; 5. 计 算 数 ; 6. 概 率 论 与 数 理 统 计 ; 7. 应 用 数 ; 8. 数. 课 程 与

More information

3 月 30 日 在 中 国 证 券 报 上 海 证 券 报 证 券 时 报 证 券 日 报 和 上 海 证 券 交 易 所 网 站 上 发 出 召 开 本 次 股 东 大 会 公 告, 该 公 告 中 载 明 了 召 开 股 东 大 会 的 日 期 网 络 投 票 的 方 式 时 间 以 及 审

3 月 30 日 在 中 国 证 券 报 上 海 证 券 报 证 券 时 报 证 券 日 报 和 上 海 证 券 交 易 所 网 站 上 发 出 召 开 本 次 股 东 大 会 公 告, 该 公 告 中 载 明 了 召 开 股 东 大 会 的 日 期 网 络 投 票 的 方 式 时 间 以 及 审 北 京 市 君 致 律 师 事 务 所 关 于 浪 潮 软 件 股 份 有 限 公 司 2015 年 度 股 东 大 会 的 法 律 意 见 书 致 : 浪 潮 软 件 股 份 有 限 公 司 北 京 市 君 致 律 师 事 务 所 ( 以 下 简 称 本 所 ) 受 浪 潮 软 件 股 份 有 限 公 司 ( 以 下 简 称 公 司 ) 的 委 托, 指 派 律 师 出 席 2016 年 4 月

More information

教师上报成绩流程图

教师上报成绩流程图 教 务 管 理 系 统 使 用 说 明 学 生 端 用 户 1 在 校 内 任 何 一 台 连 接 校 园 网 的 计 算 机 上 登 录 教 务 处 主 页 教 务 处 主 页 地 址 : http://jw.stdu.edu.cn/homepage 随 后 点 击 按 钮 ( 见 下 图 所 示 ), 即 可 进 入 综 合 教 务 管 理 系 统 2 在 综 合 教 务 管 理 区 域 内 键

More information

伊 犁 师 范 学 院 611 语 言 学 概 论 全 套 考 研 资 料 <2016 年 最 新 考 研 资 料 > 2-2 语 言 学 纲 要 笔 记, 由 考 取 本 校 本 专 业 高 分 研 究 生 总 结 而 来, 重 点 突 出, 借 助 此 笔 记 可 以 大 大 提 高 复 习 效

伊 犁 师 范 学 院 611 语 言 学 概 论 全 套 考 研 资 料 <2016 年 最 新 考 研 资 料 > 2-2 语 言 学 纲 要 笔 记, 由 考 取 本 校 本 专 业 高 分 研 究 生 总 结 而 来, 重 点 突 出, 借 助 此 笔 记 可 以 大 大 提 高 复 习 效 伊 犁 师 范 学 院 611 语 言 学 概 论 全 套 考 研 资 料 ......2 伊 犁 师 范 学 院 802 文 学 概 论 全 套 考 研 资 料 ......2 伊 犁 师 范 学 院 702 普 通 物 理 全 套 考 研 资 料 ......3 伊 犁

More information

<433A5C55736572735C6B73625C4465736B746F705CB9FABCCAD6D0D2BDD2A9D7A8D2B5B8DFBCB6BCBCCAF5D6B0B3C6C6C0C9F3C9EAC7EBD6B8C4CFA3A832303136CDA8D3C3B0E6A3A92E646F63>

<433A5C55736572735C6B73625C4465736B746F705CB9FABCCAD6D0D2BDD2A9D7A8D2B5B8DFBCB6BCBCCAF5D6B0B3C6C6C0C9F3C9EAC7EBD6B8C4CFA3A832303136CDA8D3C3B0E6A3A92E646F63> 附 件 1 国 际 中 药 专 业 高 级 技 术 职 称 评 审 条 件 及 报 名 材 料 一 系 列 ( 一 ) 中 1 高 级 专 科 ( 副 ) 高 级 专 科 ( 副 ) 1 取 得 中 专 科 职 称 后, 独 立 从 事 中 临 床 实 践 5 年 以 上 2 取 得 中 博 士 学 位 后, 临 床 实 践 2 年 以 上 3 取 得 中 硕 士 学 位 后, 临 床 实 践 7

More information

课程类 别

课程类 别 美 声 演 唱 方 向 培 养 方 案 一 培 养 目 标 本 方 向 要 求 学 生 德 智 体 美 全 面 发 展, 培 养 能 在 文 艺 团 体 从 事 声 乐 演 唱 及 能 在 艺 术 院 校 从 事 本 方 向 教 学 的 高 级 门 人 才 二 培 养 规 格 本 方 向 学 生 应 系 统 掌 握 声 乐 演 唱 方 面 的 理 论 和 技 能, 具 备 较 高 的 声 乐 演 唱

More information

名 称 生 命 科 学 学 院 083001 环 境 科 学 1 生 物 学 仅 接 收 院 内 调 剂, 初 试 分 数 满 足 我 院 生 物 学 复 试 最 低 分 数 线 生 命 科 学 学 院 071300 生 态 学 5 生 态 学 或 生 物 学 生 命 科 学 学 院 040102

名 称 生 命 科 学 学 院 083001 环 境 科 学 1 生 物 学 仅 接 收 院 内 调 剂, 初 试 分 数 满 足 我 院 生 物 学 复 试 最 低 分 数 线 生 命 科 学 学 院 071300 生 态 学 5 生 态 学 或 生 物 学 生 命 科 学 学 院 040102 华 中 师 范 大 学 2016 年 接 收 校 内 外 优 秀 硕 士 研 究 生 调 剂 信 息 表 名 称 经 济 与 工 商 管 理 学 院 020101 政 治 经 济 学 1 经 济 学 类 毕 业 学 校 与 报 考 学 校 不 低 于 我 校 办 学 层 次 经 济 与 工 商 管 理 学 院 020105 世 界 经 济 学 1 经 济 学 类 毕 业 学 校 与 报 考 学 校

More information

3 复 试 如 何 准 备 4 复 试 成 绩 计 算 5 复 试 比 例 6 复 试 类 型 7 怎 么 样 面 对 各 种 复 试 04 05

3 复 试 如 何 准 备 4 复 试 成 绩 计 算 5 复 试 比 例 6 复 试 类 型 7 怎 么 样 面 对 各 种 复 试 04 05 1 复 试 流 程 2 复 试 考 查 形 式 02 03 3 复 试 如 何 准 备 4 复 试 成 绩 计 算 5 复 试 比 例 6 复 试 类 型 7 怎 么 样 面 对 各 种 复 试 04 05 2 怎 样 给 导 师 留 下 良 好 的 第 一 印 象 把 握 进 门 时 机 1 面 试 中 穿 着 的 瞒 天 过 海 3 无 声 胜 有 声 的 肢 体 语 言 育 4 眼 睛 是 心

More information

电信系教学大纲的基本规范

电信系教学大纲的基本规范 兰 州 大 学 信 息 科 学 与 工 程 学 院 Java 语 言 程 序 设 计 实 验 教 学 大 纲 一. 课 程 基 本 信 息 : 实 验 课 程 编 号 : 课 程 名 称 : Java 语 言 程 序 设 计 实 验 课 课 程 性 质 : 非 单 列 实 验 课 课 程 类 型 : 必 做 课 程 负 责 人 : 马 俊 等 适 用 专 业 : 计 算 机 科 学 与 技 术 专

More information

全国建筑市场注册执业人员不良行为记录认定标准(试行).doc

全国建筑市场注册执业人员不良行为记录认定标准(试行).doc - 1 - - 2 - 附 件 全 国 建 筑 市 场 注 册 执 业 人 员 不 良 记 录 认 定 标 准 ( 试 行 ) 说 明 为 了 完 善 建 筑 市 场 注 册 执 业 人 员 诚 信 体 系 建 设, 规 范 执 业 和 市 场 秩 序, 依 据 相 关 法 律 法 规 和 部 门 规 章, 根 据 各 行 业 特 点, 我 部 制 订 了 全 国 建 筑 市 场 注 册 执 业 人

More information

一 从 分 封 制 到 郡 县 制 一 从 打 虎 亭 汉 墓 说 起

一 从 分 封 制 到 郡 县 制 一 从 打 虎 亭 汉 墓 说 起 县 乡 两 级 的 政 治 体 制 改 革 如 何 建 立 民 主 的 合 作 新 体 制 县 乡 人 大 运 行 机 制 研 究 课 题 组 引 言 一 从 分 封 制 到 郡 县 制 一 从 打 虎 亭 汉 墓 说 起 二 密 县 在 周 初 是 两 个 小 国 密 国 和 郐 国 三 密 县 的 第 一 任 县 令 卓 茂 四 明 清 时 代 的 密 县 二 从 集 中 的 动 员 体

More information

2 2015 年 8 月 11 日, 公 司 召 开 2015 年 第 五 次 临 时 股 东 大 会, 审 议 通 过 了 关 于 公 司 <2015 年 股 票 期 权 激 励 计 划 ( 草 案 )> 及 其 摘 要 的 议 案 关 于 提 请 股 东 大 会 授 权 董 事 会 办 理 公

2 2015 年 8 月 11 日, 公 司 召 开 2015 年 第 五 次 临 时 股 东 大 会, 审 议 通 过 了 关 于 公 司 <2015 年 股 票 期 权 激 励 计 划 ( 草 案 )> 及 其 摘 要 的 议 案 关 于 提 请 股 东 大 会 授 权 董 事 会 办 理 公 证 券 代 码 :300017 证 券 简 称 : 网 宿 科 技 公 告 编 号 :2016-053 网 宿 科 技 股 份 有 限 公 司 关 于 调 整 公 司 2015 年 股 票 期 权 激 励 计 划 激 励 对 象 股 票 期 权 数 量 和 行 权 价 格 的 公 告 本 公 司 及 董 事 会 全 体 成 员 保 证 公 告 内 容 真 实 准 确 和 完 整, 没 有 虚 假 记

More information

Microsoft Word - 资料分析练习题09.doc

Microsoft Word - 资料分析练习题09.doc 行 测 高 分 冲 刺 练 习 题 资 料 分 析 ( 共 15 题, 参 考 时 限 10 分 钟 ) 材 料 题 - 1 2012 年 1 月 某 小 区 成 交 的 二 手 房 中, 面 积 为 60 平 方 米 左 右 的 住 宅 占 总 销 售 套 数 的 ( ) A.25% B.35% C.37.5% 长 沙 市 雨 花 区 侯 家 塘 佳 天 国 际 大 厦 北 栋 20 楼 第 1

More information

导 数 和 微 分 的 概 念 导 数 的 几 何 意 义 和 物 理 意 义 函 数 的 可 导 性 与 连 续 性 之 间 的 关 系 平 面 曲 线 的 切 线 和 法 线 导 数 和 微 分 的 四 则 运 算 基 本 初 等 函 数 的 导 数 复 合 函 数 反 函 数 隐 函 数 以

导 数 和 微 分 的 概 念 导 数 的 几 何 意 义 和 物 理 意 义 函 数 的 可 导 性 与 连 续 性 之 间 的 关 系 平 面 曲 线 的 切 线 和 法 线 导 数 和 微 分 的 四 则 运 算 基 本 初 等 函 数 的 导 数 复 合 函 数 反 函 数 隐 函 数 以 2015 年 考 研 数 学 二 考 试 大 纲 考 试 科 目 : 高 等 数 学 线 性 代 数 考 试 形 式 和 试 卷 结 构 一 试 卷 满 分 及 考 试 时 间 试 卷 满 分 为 150 分, 考 试 时 间 为 180 分 钟. 二 答 题 方 式 答 题 方 式 为 闭 卷 笔 试. 三 试 卷 内 容 结 构 高 等 教 学 约 78% 线 性 代 数 约 22% 四 试 卷

More information

2016 年 荔 湾 区 财 政 核 定 支 出 汇 总 表 表 二 单 位 名 称 : 广 州 文 化 公 园 基 本 支 出 项 目 支 出 科 目 编 码 预 算 科 目 名 称 一 般 公 共 预 算 5,800.54 4,695.54 3,092.96 1,481.18 121.40 1,

2016 年 荔 湾 区 财 政 核 定 支 出 汇 总 表 表 二 单 位 名 称 : 广 州 文 化 公 园 基 本 支 出 项 目 支 出 科 目 编 码 预 算 科 目 名 称 一 般 公 共 预 算 5,800.54 4,695.54 3,092.96 1,481.18 121.40 1, 表 一 2016 年 荔 湾 区 收 支 预 算 总 表 单 位 名 称 : 广 州 文 化 公 园 预 算 收 入 预 算 支 出 项 目 预 算 数 项 目 预 算 数 一 一 般 公 共 预 算 拨 款 5,800.54 一 基 本 支 出 4,695.54 工 资 福 利 支 出 3,092.96 二 政 府 性 基 金 预 算 拨 款 商 品 和 服 务 支 出 121.40 三 国 有

More information

全国教师资格认定管理信息系统

全国教师资格认定管理信息系统 操 作 说 明 一 教 师 资 格 认 定 申 请 人 1 : 1. 未 参 加 全 国 统 考 申 请 人 2.1 登 录 未 参 加 全 国 统 考 申 请 人 网 上 报 名 系 统 登 录 中 国 教 师 资 格 网 (http://www.jszg.edu.cn), 未 参 加 全 国 统 考 申 请 人 有 两 种 途 径 进 入 报 名 系 统 第 一 种 途 径 : 点 击 网 站

More information

Template BR_Rec_2005.dot

Template BR_Rec_2005.dot ITU-R BT.1789 建 议 书 1 ITU-R BT.1789 建 议 书 在 分 组 视 频 传 输 中 利 用 传 输 误 码 信 息 重 建 接 收 视 频 的 方 法 (ITU-R 44/6 和 ITU-R 109/6 课 题 ) (2007 年 ) 范 围 本 建 议 书 对 业 务 提 供 商 重 建 接 收 视 频 的 方 法 做 了 详 细 介 绍, 以 便 利 用 传 输

More information

现 场 会 议 时 间 为 :2016 年 5 月 19 日 网 络 投 票 时 间 为 :2016 年 5 月 18 日 -2016 年 5 月 19 日 其 中 通 过 深 圳 证 券 交 易 所 交 易 系 统 进 行 网 络 投 票 的 时 间 为 2016 年 5 月 19 日 9:30-

现 场 会 议 时 间 为 :2016 年 5 月 19 日 网 络 投 票 时 间 为 :2016 年 5 月 18 日 -2016 年 5 月 19 日 其 中 通 过 深 圳 证 券 交 易 所 交 易 系 统 进 行 网 络 投 票 的 时 间 为 2016 年 5 月 19 日 9:30- 证 券 代 码 :300439 证 券 简 称 : 美 康 生 物 公 告 编 号 :2016-046 宁 波 美 康 生 物 科 技 股 份 有 限 公 司 2015 年 度 股 东 大 会 决 议 公 告 公 司 及 董 事 会 全 体 成 员 保 证 信 息 披 露 的 内 容 真 实 准 确 完 整, 没 有 虚 假 记 载 误 导 性 陈 述 或 重 大 遗 漏 特 别 提 示 : 1 2016

More information

上海证券交易所会议纪要

上海证券交易所会议纪要 附 件 上 海 市 场 首 次 公 开 发 行 股 票 网 下 发 行 实 施 细 则 第 一 章 总 则 第 一 条 为 规 范 拟 在 上 海 证 券 交 易 所 ( 以 下 简 称 上 交 所 ) 上 市 的 公 司 首 次 公 开 发 行 股 票 网 下 发 行 业 务, 提 高 首 次 公 开 发 行 股 票 网 下 申 购 及 资 金 结 算 效 率, 根 据 证 券 发 行 与 承 销

More information

一、资质申请

一、资质申请 二 工 程 监 理 企 业 资 质 有 关 问 答 111 什 么 样 的 企 业 可 以 在 本 省 申 请 工 程 监 理 企 业 资 质? 答 : 在 鄂 取 得 法 人 营 业 执 照 或 合 伙 企 业 营 业 执 照 的 企 业, 都 可 依 法 向 工 商 注 册 所 在 省 或 市 建 设 行 政 主 管 部 门 行 政 审 批 部 门 申 请 工 程 监 理 企 业 资 质 取 得

More information

附 件 : 上 海 市 建 筑 施 工 企 业 施 工 现 场 项 目 管 理 机 构 关 键 岗 位 人 员 配 备 指 南 二 一 四 年 九 月 十 一 日 2

附 件 : 上 海 市 建 筑 施 工 企 业 施 工 现 场 项 目 管 理 机 构 关 键 岗 位 人 员 配 备 指 南 二 一 四 年 九 月 十 一 日 2 公 开 上 海 市 城 乡 建 设 和 管 理 委 员 会 文 件 沪 建 管 2014 758 号 上 海 市 城 乡 建 设 和 管 理 委 员 会 关 于 印 发 上 海 市 建 筑 施 工 企 业 施 工 现 场 项 目 管 理 机 构 关 键 岗 位 人 员 配 备 指 南 的 通 知 各 区 县 建 设 和 交 通 委 员 会 : 为 进 一 步 加 强 对 建 设 工 程 施 工 现

More information

云信Linux SSH认证代理用户手册

云信Linux SSH认证代理用户手册 Windows 主 机 登 录 保 护 (RDP) 管 理 员 配 置 手 册 V1.0 云 信 事 业 部 飞 天 诚 信 科 技 股 份 有 限 公 司 www.cloudentify.com 章 节 目 录 第 1 章 管 理 平 台 配 置 说 明... 1 1.1 注 册... 1 1.2 登 录... 3 1.3 添 加 应 用... 4 1.4 添 加 用 户... 7 1.5 激 活

More information

21 业 余 制 -- 高 起 专 (12 级 ) 75 元 / 学 分 网 络 学 院 学 生 沪 教 委 财 (2005)49 号 江 西 化 校 工 科 22 业 余 制 -- 高 起 专 (12 级 ) 70 元 / 学 分 网 络 学 院 学 生 沪 教 委 财 (2005)49 号 吉

21 业 余 制 -- 高 起 专 (12 级 ) 75 元 / 学 分 网 络 学 院 学 生 沪 教 委 财 (2005)49 号 江 西 化 校 工 科 22 业 余 制 -- 高 起 专 (12 级 ) 70 元 / 学 分 网 络 学 院 学 生 沪 教 委 财 (2005)49 号 吉 1 普 通 高 校 学 费 5000 元 / 学 年 一 般 专 业 2 普 通 高 校 学 费 5500 元 / 学 年 特 殊 专 业 3 普 通 高 校 学 费 10000 元 / 学 年 艺 术 专 业 4 中 德 合 作 办 学 15000 元 / 学 年 本 科 生 本 科 学 费 5 ( 含 港 澳 修 读 第 二 专 业 辅 修 专 业 及 学 位 学 费 不 超 过 选 读 专 业

More information

新, 各 地 各 部 门 ( 单 位 ) 各 文 化 事 业 单 位 要 高 度 重 视, 切 实 加 强 领 导, 精 心 组 织 实 施 要 根 据 事 业 单 位 岗 位 设 置 管 理 的 规 定 和 要 求, 在 深 入 调 查 研 究 广 泛 听 取 意 见 的 基 础 上, 研 究 提

新, 各 地 各 部 门 ( 单 位 ) 各 文 化 事 业 单 位 要 高 度 重 视, 切 实 加 强 领 导, 精 心 组 织 实 施 要 根 据 事 业 单 位 岗 位 设 置 管 理 的 规 定 和 要 求, 在 深 入 调 查 研 究 广 泛 听 取 意 见 的 基 础 上, 研 究 提 广 西 壮 族 自 治 区 人 事 厅 广 西 壮 族 自 治 区 文 化 厅 文 件 桂 人 发 2009 42 号 关 于 印 发 广 西 壮 族 自 治 区 文 化 事 业 单 位 岗 位 设 置 结 构 比 例 指 导 标 准 的 通 知 各 市 人 事 局 文 化 局, 区 直 各 部 门 ( 单 位 ): 根 据 人 事 部 印 发 的 事 业 单 位 岗 位 设 置 管 理 试 行 办

More information

<4D6963726F736F667420576F7264202D20B3D6B2D6CFDEB6EEB1EDB8F1D7EED6D52E646F63>

<4D6963726F736F667420576F7264202D20B3D6B2D6CFDEB6EEB1EDB8F1D7EED6D52E646F63> 国 内 各 期 货 交 易 所 关 于 合 约 限 仓 方 面 的 规 定 上 海 期 货 交 易 所 经 纪 会 员 非 经 纪 会 员 和 客 户 的 期 货 合 约 在 不 同 时 期 限 仓 的 具 体 比 例 和 数 额 如 下 : ( 单 位 : ) 合 约 挂 牌 至 交 割 月 前 第 二 月 的 最 后 一 个 交 易 日 交 割 月 前 第 一 月 交 割 月 份 某 一 期 货

More information

黄 金 原 油 总 持 仓 增 长, 同 比 增 幅 分 别 为 4.2% 和 4.1% 而 铜 白 银 以 及 玉 米 则 出 现 减 持, 减 持 同 比 减 少 分 别 为 9.4%,9.4% 以 及 6.5% 大 豆, 豆 粕 结 束 连 续 4 周 总 持 仓 量 增 长, 出 现 小 幅

黄 金 原 油 总 持 仓 增 长, 同 比 增 幅 分 别 为 4.2% 和 4.1% 而 铜 白 银 以 及 玉 米 则 出 现 减 持, 减 持 同 比 减 少 分 别 为 9.4%,9.4% 以 及 6.5% 大 豆, 豆 粕 结 束 连 续 4 周 总 持 仓 量 增 长, 出 现 小 幅 小 麦 净 多 持 仓 增 加, 豆 油 豆 粕 净 多 持 仓 减 少 美 国 CFTC 持 仓 报 告 部 门 : 市 场 研 究 与 开 发 部 类 型 : 量 化 策 略 周 报 日 期 :212 年 5 月 7 日 电 话 :592-5678753 网 址 :www.jinyouqh.com 主 要 内 容 : 根 据 美 国 CFTC 公 布 的 数 据, 本 报 告 中 的 11 个

More information

¹ º ¹ º 农 业 流 动 人 口 是 指 户 口 性 质 为 农 业 户 口 在 流 入 地 城 市 工 作 生 活 居 住 一 个 月 及 以 上 的 流 动 人 口 非 农 流 动 人 口 是 指 户 口 性 质 为 非 农 户 口 在 流 入 地 城 市 工 作 生 活 居 住 一 个

¹ º ¹ º 农 业 流 动 人 口 是 指 户 口 性 质 为 农 业 户 口 在 流 入 地 城 市 工 作 生 活 居 住 一 个 月 及 以 上 的 流 动 人 口 非 农 流 动 人 口 是 指 户 口 性 质 为 非 农 户 口 在 流 入 地 城 市 工 作 生 活 居 住 一 个 ¹ 改 革 开 放 年 来 人 口 流 动 规 模 持 续 增 加 对 我 国 社 会 经 济 的 持 续 发 展 起 到 了 重 要 作 用 为 全 面 了 解 我 国 流 动 人 口 生 存 状 况 准 确 把 握 流 动 人 口 发 展 规 律 和 趋 势 不 断 加 强 流 动 人 口 服 务 管 理 引 导 人 口 有 序 流 动 合 理 分 布 国 家 人 口 计 生 委 于 年 月 启

More information

上海证券交易所会议纪要

上海证券交易所会议纪要 附 件 上 海 市 场 首 次 公 开 发 行 股 票 网 上 发 行 实 施 细 则 第 一 章 总 则 第 一 条 为 规 范 上 海 市 场 首 次 公 开 发 行 股 票 网 上 发 行 行 为, 根 据 证 券 发 行 与 承 销 管 理 办 法 及 相 关 规 定, 制 定 本 细 则 第 二 条 通 过 上 海 证 券 交 易 所 ( 以 下 简 称 上 交 所 ) 交 易 系 统 并

More information

收 入 支 出 项 目 2016 年 预 算 项 目 2016 年 预 算 预 算 01 表 单 位 : 万 元 ( 保 留 两 位 小 数 ) 一 公 共 财 政 预 算 拨 款 50.06 一 人 员 经 费 23.59 1 一 般 财 力 50.06 1 人 员 支 出 21.95 2 成 品

收 入 支 出 项 目 2016 年 预 算 项 目 2016 年 预 算 预 算 01 表 单 位 : 万 元 ( 保 留 两 位 小 数 ) 一 公 共 财 政 预 算 拨 款 50.06 一 人 员 经 费 23.59 1 一 般 财 力 50.06 1 人 员 支 出 21.95 2 成 品 100.12 2016 年 龙 岩 市 部 门 预 算 表 报 送 日 期 : 年 月 日 单 位 负 责 人 签 章 : 财 务 负 责 人 签 章 : 制 表 人 签 章 : 收 入 支 出 项 目 2016 年 预 算 项 目 2016 年 预 算 预 算 01 表 单 位 : 万 元 ( 保 留 两 位 小 数 ) 一 公 共 财 政 预 算 拨 款 50.06 一 人 员 经 费 23.59

More information

4 进 入 交 互 区 设 置 的 组 件 管 理, 在 组 件 管 理 中, 教 师 可 以 选 择 课 程 空 间 中 的 所 有 组 件, 并 通 过 点 击 启 用 或 不 启 用 选 定 组 件 在 课 程 空 间 中 的 显 示 5 进 入 工 作 室 管 理 的 工 作 室 首 页,

4 进 入 交 互 区 设 置 的 组 件 管 理, 在 组 件 管 理 中, 教 师 可 以 选 择 课 程 空 间 中 的 所 有 组 件, 并 通 过 点 击 启 用 或 不 启 用 选 定 组 件 在 课 程 空 间 中 的 显 示 5 进 入 工 作 室 管 理 的 工 作 室 首 页, 网 络 教 育 新 平 台 教 师 使 用 简 易 手 册 一 登 录 教 师 工 作 室 1 打 开 西 南 科 技 大 学 网 络 教 育 教 学 教 务 新 平 台 主 页 面 :http://www.swust.net.cn/ 2 在 主 页 面 左 边 的 登 陆 区 中, 用 户 名 和 密 码 处 分 别 输 入 自 己 的 用 户 名 ( 教 师 ID 号 ) 和 密 码 ( 初 始

More information

上证指数

上证指数 上 证 与 修 正 方 法 一 ( 一 ) 计 算 公 式 1. 上 证 指 数 系 列 均 采 用 派 许 加 权 综 合 价 格 指 数 公 式 计 算 2. 上 证 180 指 数 上 证 50 指 数 等 以 成 份 股 的 调 整 股 本 数 为 权 数 进 行 加 权 计 算, 计 算 公 式 为 : 报 告 期 指 数 =( 报 告 期 样 本 股 的 调 整 市 值 / 基 期 )

More information

01

01 Zebra Technologies 利 用 移 动 技 术 提 高 货 运 公 司 工 作 效 率 和 成 本 效 益 货 运 物 流 自 动 化 案 例 在 当 前 严 峻 的 经 济 形 势 下, 公 路 货 运 公 司 开 始 寻 求 提 高 效 率 降 低 运 营 开 支 和 保 留 客 户 的 有 效 途 径 然 而, 他 们 面 临 的 冷 酷 现 实 是 燃 料 价 格 难 以 预

More information

抗 日 战 争 研 究 年 第 期

抗 日 战 争 研 究 年 第 期 田 子 渝 武 汉 抗 战 时 期 是 国 共 第 二 次 合 作 的 最 好 时 期 在 国 共 合 作 的 基 础 上 出 现 了 抗 日 救 亡 共 御 外 侮 的 局 面 这 个 大 好 局 面 的 出 现 与 中 共 长 江 局 的 丰 功 伟 绩 是 分 不 开 的 但 长 期 以 来 由 于 有 一 个 王 明 的 右 倾 错 误 直 接 影 响 了 对 它 的 全 面 科 学 准 确

More information

作 为 生 产 者 式 文 本 的 女 性 主 义 通 俗 小 说 梅 丽 本 文 借 鉴 文 化 研 究 理 论 家 约 翰 费 斯 克 的 生 产 者 式 文 本 这 一 概 念 考 察 女 性 主 义 通 俗 小 说 的 文 本 特 征 写 作 策 略 和 微 观 政 治 意 义 女 性 主 义 通 俗 小 说 通 过 对 传 统 通 俗 小 说 的 挪 用 和 戏 仿 传 播 女 性 主 义

More information

自 服 务 按 钮 无 法 访 问 新 系 统 的 自 服 务 页 面 因 此 建 议 用 户 从 信 网 中 心 (http://nc.tju.edu.cn) 主 页, 右 下 角 位 置 的 常 用 下 载, 或 校 园 网 用 户 自 服 务 (http://g.tju.edu.cn) 首 页

自 服 务 按 钮 无 法 访 问 新 系 统 的 自 服 务 页 面 因 此 建 议 用 户 从 信 网 中 心 (http://nc.tju.edu.cn) 主 页, 右 下 角 位 置 的 常 用 下 载, 或 校 园 网 用 户 自 服 务 (http://g.tju.edu.cn) 首 页 校 园 网 认 证 计 费 系 统 变 更 说 明 及 使 用 帮 助 为 提 高 校 园 网 的 可 靠 性 和 可 用 性, 提 升 用 户 的 上 网 体 验, 同 时 也 为 解 决 近 期 校 园 网 无 法 认 证 或 登 录 页 面 弹 出 缓 慢 的 问 题, 信 网 中 心 于 近 期 对 校 园 网 认 证 计 费 系 统 进 行 升 级 切 换 现 将 升 级 后 新 系 统

More information

关于修订《沪市股票上网发行资金申购

关于修订《沪市股票上网发行资金申购 关 于 修 订 沪 市 股 票 上 网 发 行 资 金 申 购 实 施 办 法 的 通 知 各 有 关 单 位 : 沪 市 股 票 上 网 发 行 资 金 申 购 实 施 办 法 ( 修 订 稿 ) ( 见 附 件 ) 已 经 中 国 证 券 监 督 管 理 委 员 会 批 准, 现 将 修 订 所 涉 主 要 内 容 公 布 如 下 一 第 二 条 ( 二 ) 申 购 单 位 及 上 限 修 改

More information

光明乳业股份有限公司

光明乳业股份有限公司 光 明 乳 业 股 份 有 限 公 司 非 公 开 发 行 A 股 股 票 募 集 资 金 存 放 与 实 际 使 用 情 况 的 专 项 报 告 及 审 核 报 告 截 至 2012 年 12 月 31 日 止 审 核 报 告 光 明 乳 业 股 份 有 限 公 司 全 体 股 东 : 德 师 报 ( 核 ) 字 (13) 第 E0019 号 我 们 审 核 了 后 附 的 光 明 乳 业 股 份

More information

西 南 大 学 硕 士 学 位 论 文 网 络 购 物 动 机 问 卷 的 编 制 及 实 测 姓 名 : 曹 建 英 申 请 学 位 级 别 : 硕 士 专 业 : 基 础 心 理 学 指 导 教 师 : 张 进 辅 20090401 网 络 购 物 动 机 问 卷 的

More information

2015-2016 学 年 第 二 学 期 集 中 考 试 安 排 (18 周 ) 考 试 日 期 :6 月 27 日 星 期 一 8:10-9:50 第 二 公 共 教 学 楼 A 区 A303 10811046 高 等 数 学 ( 理 二 2) 复 材 1501-2 材 料 科 学 与 工 程

2015-2016 学 年 第 二 学 期 集 中 考 试 安 排 (18 周 ) 考 试 日 期 :6 月 27 日 星 期 一 8:10-9:50 第 二 公 共 教 学 楼 A 区 A303 10811046 高 等 数 学 ( 理 二 2) 复 材 1501-2 材 料 科 学 与 工 程 考 试 时 间 2015-2016 学 年 第 二 学 期 集 中 考 试 安 排 (18 周 ) 考 试 日 期 :6 月 27 日 星 期 一 考 场 所 在 教 学 楼 ( 教 学 区 ) 考 试 教 室 课 程 号 课 程 名 考 生 所 在 专 业 ( 班 级 ) 考 生 所 属 学 院 8:10-9:50 第 二 公 共 教 学 楼 A 区 A101 10811026 高 等 数 学 (

More information

超 级 玛 丽 JAVA 小 游 戏 测 试 报 告 1. 导 言 1.1 编 写 目 的 该 文 档 的 目 的 是 描 述 超 级 玛 丽 JAVA 小 游 戏 的 系 统 测 试 的 总 结 报 告, 其 主 要 内 容 包 括 : 系 统 环 境 的 介 绍 功 能 的 实 现 的 测 试

超 级 玛 丽 JAVA 小 游 戏 测 试 报 告 1. 导 言 1.1 编 写 目 的 该 文 档 的 目 的 是 描 述 超 级 玛 丽 JAVA 小 游 戏 的 系 统 测 试 的 总 结 报 告, 其 主 要 内 容 包 括 : 系 统 环 境 的 介 绍 功 能 的 实 现 的 测 试 超 级 玛 丽 游 戏 测 试 报 告 目 录 1. 导 言... 2 1.1 编 写 目 的... 2 1.2 项 目 范 围... 2 1.3 参 考 资 料... 2 1.4 缩 写 说 明... 2 1.5 术 语 定 义... 2 1.6 版 本 更 新 信 息... 3 2. 测 试 设 计... 3 2.1 测 试 要 点... 3 2.2 测 试 时 间 地 点 人 员... 3 2.3

More information

一 开 放 性 的 政 策 与 法 规 二 两 岸 共 同 的 文 化 传 承 三 两 岸 高 校 各 自 具 有 专 业 优 势 远 见 杂 志 年 月 日

一 开 放 性 的 政 策 与 法 规 二 两 岸 共 同 的 文 化 传 承 三 两 岸 高 校 各 自 具 有 专 业 优 势 远 见 杂 志 年 月 日 河 北 师 范 大 学 学 报 新 时 期 海 峡 两 岸 高 校 开 放 招 生 问 题 探 讨 郑 若 玲 王 晓 勇 海 峡 两 岸 高 校 开 放 招 生 是 新 时 期 推 进 海 峡 两 岸 高 等 教 育 交 流 与 合 作 的 重 要 尝 试 系 统 梳 理 改 革 开 放 以 来 两 岸 招 生 政 策 与 就 学 人 数 发 展 变 化 的 历 史 进 程 可 发 现 促 进 两

More information

第 六 章 债 券 股 票 价 值 评 估 1 考 点 一 : 债 券 价 值 的 影 响 因 素 2

第 六 章 债 券 股 票 价 值 评 估 1 考 点 一 : 债 券 价 值 的 影 响 因 素 2 Professional Accounting Education Provided by Academy of Professional Accounting (APA) CPA 财 务 管 理 习 题 班 第 八 讲 债 券 股 票 价 值 评 估 IreneGao ACCAspace 中 国 ACCA 国 际 注 册 会 计 师 教 育 平 台 Copyright ACCAspace.com

More information

第二讲 数列

第二讲   数列 Togisu XueD Persolized Eduio Developme Ceer 高 考 中 不 等 式 问 题 的 解 决 方 法 通 润 达 久 王 力 前 言 : 近 年 来 不 等 式 问 题 正 越 来 越 多 的 出 现 在 调 研 题 和 高 考 试 题 中 而 且 大 多 出 现 在 江 苏 高 考 的 填 空 压 轴 题 中 是 高 考 考 察 的 重 点 和 难 点 由 于

More information

( 此 页 无 正 文, 为 广 东 东 方 精 工 科 技 股 份 有 限 公 司 关 于 提 供 资 料 真 实 准 确 和 完 整 的 承 诺 函 之 签 署 页 ) 广 东 东 方 精 工 科 技 股 份 有 限 公 司 法 定 代 表 人 : 唐 灼 林 2016 年 7 月 28 日

( 此 页 无 正 文, 为 广 东 东 方 精 工 科 技 股 份 有 限 公 司 关 于 提 供 资 料 真 实 准 确 和 完 整 的 承 诺 函 之 签 署 页 ) 广 东 东 方 精 工 科 技 股 份 有 限 公 司 法 定 代 表 人 : 唐 灼 林 2016 年 7 月 28 日 广 东 东 方 精 工 科 技 股 份 有 限 公 司 关 于 提 供 资 料 真 实 准 确 和 完 整 的 承 诺 函 鉴 于 广 东 东 方 精 工 科 技 股 份 有 限 公 司 ( 以 下 简 称 本 公 司 ) 拟 收 购 北 京 普 莱 德 新 能 源 电 池 科 技 有 限 公 司 股 权, 为 保 证 本 次 交 易 的 顺 利 完 成, 按 照 中 国 证 券 监 管 部 门 相

More information

正 规 培 训 达 规 定 标 准 学 时 数, 并 取 得 结 业 证 书 二 级 可 编 程 师 ( 具 备 以 下 条 件 之 一 者 ) (1) 连 续 从 事 本 职 业 工 作 13 年 以 上 (2) 取 得 本 职 业 三 级 职 业 资 格 证 书 后, 连 续 从 事 本 职 业

正 规 培 训 达 规 定 标 准 学 时 数, 并 取 得 结 业 证 书 二 级 可 编 程 师 ( 具 备 以 下 条 件 之 一 者 ) (1) 连 续 从 事 本 职 业 工 作 13 年 以 上 (2) 取 得 本 职 业 三 级 职 业 资 格 证 书 后, 连 续 从 事 本 职 业 1. 职 业 概 况 1.1 职 业 名 称 可 编 程 师 1.2 职 业 定 义 可 编 程 师 国 家 职 业 标 准 从 事 可 编 程 序 控 制 器 (PLC) 选 型 编 程, 并 对 应 用 进 行 集 成 和 运 行 管 理 的 人 员 1.3 职 业 等 级 本 职 业 共 设 四 个 等 级, 分 别 为 : 四 级 可 编 程 师 ( 国 家 职 业 资 格 四 级 ) 三

More information

工 程 勘 察 资 质 标 准 根 据 建 设 工 程 勘 察 设 计 管 理 条 例 和 建 设 工 程 勘 察 设 计 资 质 管 理 规 定, 制 定 本 标 准 一 总 则 ( 一 ) 本 标 准 包 括 工 程 勘 察 相 应 专 业 类 型 主 要 专 业 技 术 人 员 配 备 技 术

工 程 勘 察 资 质 标 准 根 据 建 设 工 程 勘 察 设 计 管 理 条 例 和 建 设 工 程 勘 察 设 计 资 质 管 理 规 定, 制 定 本 标 准 一 总 则 ( 一 ) 本 标 准 包 括 工 程 勘 察 相 应 专 业 类 型 主 要 专 业 技 术 人 员 配 备 技 术 住 房 和 城 乡 建 设 部 关 于 印 发 工 程 勘 察 资 质 标 准 的 通 知 建 市 [2013]9 号 各 省 自 治 区 住 房 和 城 乡 建 设 厅, 北 京 市 规 划 委, 天 津 上 海 市 建 设 交 通 委, 重 庆 市 城 乡 建 设 委, 新 疆 生 产 建 设 兵 团 建 设 局, 总 后 基 建 营 房 部 工 程 局, 国 务 院 有 关 部 门 建 设 司,

More information

Microsoft Word - 中节能_工业项目节能评估审查导则Draft.doc

Microsoft Word - 中节能_工业项目节能评估审查导则Draft.doc 0 -------------------------------------------------------------------------------- 2 ----------------------------------------------------------------------------- 2 节 评 ----------------------------------------------------------------------------------------------------

More information

<443A5C6D B5C30312EB9A4D7F7CEC4B5B55C30322EBACFCDACCEC4B5B55C C30342EC8CBC9E7CCFC5C31332ECFEEC4BFC5E0D1B55C E30385C322EB2D9D7F7CAD6B2E12E646F63>

<443A5C6D B5C30312EB9A4D7F7CEC4B5B55C30322EBACFCDACCEC4B5B55C C30342EC8CBC9E7CCFC5C31332ECFEEC4BFC5E0D1B55C E30385C322EB2D9D7F7CAD6B2E12E646F63> 浙 江 职 业 能 力 建 设 信 息 系 统 职 业 技 能 鉴 定 考 务 管 理 用 户 操 作 手 册 二 〇 一 五 年 八 月 目 录 0. 系 统 概 述...3 0.0. 简 要 概 述...3 0.1. 业 务 流 程 图... 3 1. 考 生 网 上 报 名... 3 1.0. 考 生 用 户 注 册 登 录... 5 1.1. 报 名 及 下 载 打 印 报 名 申 请 表...7

More information

<4D6963726F736F667420576F7264202D20B6C0C1A2B6ADCAC2D0ECCCFABEFDCFC8C9FABCB0CCE1C3FBC8CBC9F9C3F72E646F63>

<4D6963726F736F667420576F7264202D20B6C0C1A2B6ADCAC2D0ECCCFABEFDCFC8C9FABCB0CCE1C3FBC8CBC9F9C3F72E646F63> 证 券 代 码 :000420 证 券 简 称 : 吉 林 化 纤 公 告 编 号 :2010-20 吉 林 化 纤 股 份 有 限 公 司 第 六 届 董 事 会 独 立 董 事 提 名 人 声 明 提 名 人 吉 林 化 纤 股 份 有 限 公 司 董 事 会 现 提 名 徐 铁 君 先 生 为 本 公 司 第 六 届 董 事 会 独 立 董 事 候 选 人, 并 发 表 公 开 声 明, 被

More information

目 录 第 一 章 博 星 卓 越 电 子 商 务 营 销 策 划 实 践 平 台 硬 件 使 用 介 绍... 3 第 二 章 博 星 卓 越 电 子 商 务 营 销 策 划 实 践 平 台 管 理 员 端 功 能 使 用 介 绍... 4 2.1 系 统 管 理 员 登 陆... 4 2.2 班

目 录 第 一 章 博 星 卓 越 电 子 商 务 营 销 策 划 实 践 平 台 硬 件 使 用 介 绍... 3 第 二 章 博 星 卓 越 电 子 商 务 营 销 策 划 实 践 平 台 管 理 员 端 功 能 使 用 介 绍... 4 2.1 系 统 管 理 员 登 陆... 4 2.2 班 博 星 卓 越 电 子 商 务 营 销 策 划 实 践 平 台 使 用 说 明 书 制 作 : 北 京 博 导 前 程 信 息 技 术 有 限 公 司 目 录 第 一 章 博 星 卓 越 电 子 商 务 营 销 策 划 实 践 平 台 硬 件 使 用 介 绍... 3 第 二 章 博 星 卓 越 电 子 商 务 营 销 策 划 实 践 平 台 管 理 员 端 功 能 使 用 介 绍... 4 2.1

More information

年 第 期 % %! & % % % % % % &

年 第 期 % %! & % % % % % % & 国 际 关 系 理 论 类 比 认 知 与 毛 泽 东 的 对 外 政 策 张 清 敏 潘 丽 君 人 的 认 识 过 程 经 常 受 到 认 知 能 力 有 限 决 策 环 境 不 确 定 以 及 信 息 过 量 等 问 题 的 制 约 在 这 个 过 程 中 人 们 经 常 借 用 类 比 从 历 史 中 寻 找 启 发 帮 助 认 知 环 境 和 制 定 政 策 作 者 依 据! 毛 泽 东

More information

全国艺术科学规划项目

全国艺术科学规划项目 全 国 艺 术 科 学 规 划 项 目 网 上 申 报 常 见 问 题 及 解 决 方 法 目 录 一 申 报 流 程...4 二 立 项 流 程...5 三 常 见 问 题 与 处 理...6 (1). 如 何 注 册...6 (2). 系 统 中 没 有 我 的 单 位 怎 么 办?...7 (3). 在 注 册 时 写 错 身 份 证 号 名 字 而 系 统 中 不 能 修 改 怎 么 办?...

More information

定 位 和 描 述 : 程 序 设 计 / 办 公 软 件 高 级 应 用 级 考 核 内 容 包 括 计 算 机 语 言 与 基 础 程 序 设 计 能 力, 要 求 参 试 者 掌 握 一 门 计 算 机 语 言, 可 选 类 别 有 高 级 语 言 程 序 设 计 类 数 据 库 编 程 类

定 位 和 描 述 : 程 序 设 计 / 办 公 软 件 高 级 应 用 级 考 核 内 容 包 括 计 算 机 语 言 与 基 础 程 序 设 计 能 力, 要 求 参 试 者 掌 握 一 门 计 算 机 语 言, 可 选 类 别 有 高 级 语 言 程 序 设 计 类 数 据 库 编 程 类 全 国 计 算 机 等 级 考 试 调 整 方 案 2011 年 7 月, 教 育 部 考 试 中 心 组 织 召 开 了 第 五 届 全 国 计 算 机 等 级 考 试 (NCRE) 考 委 会 会 议, 会 议 完 成 NCRE 考 委 会 换 届 选 举, 并 确 定 了 下 一 步 改 革 和 发 展 的 目 标 在 新 的 历 史 时 期,NCRE 将 以 保 持 稳 定 为 前 提 以

More information

第 一 部 分 MagiCAD for Revit 安 装 流 程

第 一 部 分 MagiCAD for Revit 安 装 流 程 MagiCAD 软 件 安 装 流 程 MagiCAD v2015.4 for Revit 广 联 达 软 件 股 份 有 限 公 司 BIM 中 心 编 写 2015 年 06 月 第 一 部 分 MagiCAD for Revit 安 装 流 程 一 安 装 前 需 要 确 认 的 内 容 安 装 MagiCAD 程 序 之 前, 请 您 先 确 定 以 下 事 宜 1. 当 前 用 户 账 户

More information

<4D6963726F736F667420576F7264202D2032303133C4EAB9A4B3CCCBB6CABFCAFDD1A7D7A8D2B5BFCEBFBCCAD4B4F3B8D9D3EBD2AAC7F3>

<4D6963726F736F667420576F7264202D2032303133C4EAB9A4B3CCCBB6CABFCAFDD1A7D7A8D2B5BFCEBFBCCAD4B4F3B8D9D3EBD2AAC7F3> 工 程 硕 士 数 学 考 试 大 纲 与 要 求 ( 包 括 高 等 数 学 和 线 性 代 数 ) 一 函 数 极 限 与 连 续 第 一 部 分 : 高 等 数 学 考 试 内 容 函 数 的 概 念 及 表 示 法 函 数 的 有 界 性 单 调 性 周 期 性 和 奇 偶 性 复 合 函 数 反 函 数 分 段 函 数 和 隐 函 数 基 本 初 等 函 数 的 性 质 及 其 图 形 初

More information

2. 本 次 修 改 后, 投 资 者 申 购 新 股 的 持 有 市 值 要 求 市 值 计 算 规 则 及 证 券 账 户 使 用 的 相 关 规 定 是 否 发 生 了 变 化? 答 : 未 发 生 变 化 投 资 者 申 购 新 股 的 持 有 市 值 是 指, 以 投 资 者 为 单 位

2. 本 次 修 改 后, 投 资 者 申 购 新 股 的 持 有 市 值 要 求 市 值 计 算 规 则 及 证 券 账 户 使 用 的 相 关 规 定 是 否 发 生 了 变 化? 答 : 未 发 生 变 化 投 资 者 申 购 新 股 的 持 有 市 值 是 指, 以 投 资 者 为 单 位 新 股 网 上 网 下 发 行 实 施 细 则 问 答 上 交 所 2016-01-05 一 网 上 发 行 业 务 问 答 1. 本 次 修 改 的 主 要 内 容 是 什 么? 答 : 本 次 修 改 的 主 要 内 容 包 括 : 一 是 取 消 了 投 资 者 在 申 购 委 托 时 应 全 额 缴 纳 申 购 资 金 的 规 定, 明 确 了 投 资 者 应 根 据 最 终 确 定 的 发

More information

反 学 校 文 化 与 阶 级 再 生 产 小 子 与 子 弟 之 比 较 周 潇 作 者 通 过 对 北 京 某 打 工 子 弟 学 校 的 田 野 调 查 后 发 现 在 农 民 工 子 弟 中 间 盛 行 着 类 似 学 做 工 中 所 描 述 的 工 人 阶 级 小 子 的 反 学 校 文 化 但 是 由 于 制 度 安 排 与 社 会 条 件 的 差 异 子 弟 与 小 子 的 反 学 校

More information