Java语言3
第 三 章 Java程 序 設 計 基 礎
3.1 Java編 程 概 況 現 在 你 可 以 復 習 一 下Java語 言 的 背 景 材 料, 它 的 基 本 結 構 象C/C++, 但 任 何 用 面 向 過 程 語 言 編 寫 過 程 序 的 人 都 可 以 了 解Java語 言 的 大 部 分 結 構. 3.1.1 程 序 結 構 Java語 言 的 源 程 序 代 碼 由 一 個 或 多 個 編 譯 單 元(compilation unit)組 成, 每 個 編 譯 單 元 只 能 包 含 下 列 內 容(空 格 和 注 釋 除 外): * 一 個 程 序 包 語 句(package statement ) * 入 口 語 句(import statements) * 類 的 聲 明(class declarations) * 界 面 聲 明(interface declarations) 每 個Java的 編 譯 單 元 可 包 含 多 個 類 或 界 面, 但 是 每 個 編 譯 單 元 最 多 只 能 有 一 個 類 或 者 界 面 是 公 共 的。 Java 的 源 程 序 代 碼 被 編 譯 ?reg; 后, 便 產 生 了Java字 節 代 碼。Java的 字 節 代 碼 由 一 ?copy; 不 依 賴 于 機 器 的 指 令 組 成, 這 ?copy; 指 令 能 被Java的 運 行 系 統(runtime system)有 效 地 解 釋。Java的 運 行 系 統 工 作 起 來 如 同 一 臺 虛 擬 機。 在 當 前 的Java實 現 中, 每 個 編 譯 單 元 就 是 一 個 以.java為 后 綴 的 文 件。 每 個 編 譯 單 元 有 若 干 個 類, 編 譯 后, 每 個 類 生 成 一 個.class文 件。.class文 件 是Java虛 擬 機 能 夠 識 別 的 代 碼。3.1.2 注 釋 三 種 類 型 如 下: //注 釋 一 行 /*一 行 或 多 行 注 釋*/ /**文 檔 注 釋**/ 文 檔 注 釋 一 般 放 在 一 個 變 量 或 函 數 定 義 ?reg; 前,指 示 在 任 何 自 動 生 成 文 檔 系 統 中 調 入。 這 ?copy; 注 釋 都 是 聲 明 條 目 的 描 述.。 3.1.3 標 識 符 變 量, 函 數, 類 和 對 象 的 名 稱 都 是 標 識 符, 程 序 員 需 要 標 識 和 使 用 的 東 西 都 需 要 標 識 符。 在Java語 言 里,標 識 符 以 字 符 或_,$開 頭,后 面 可 以 包 含 數 字, 標 識 符 是 大 小 寫 有 區 別 的,沒 有 長 度 限 制。 有 效 的 標 識 符 myname ict_network Hello _sys_path $bill 例 子: int a_number; char _onechar; float $bill; 關 鍵 詞 abstract continue for new switch boolean default goto null synchronized break do if package this byte double implements private threadsafe byvalue else import protected throw case extends instanceof public transient catch false int return true char final interface short try class finally long static void const float native super while 其 它 保 留 詞 以 下 單 詞 被 保 留 使 用: cast future generic inner operator outer rest var 3.1.4 數 據 類 型 Java使 用 五 種 基 本 類 型:integer(整 數),floating(浮點 數),point(指 針),Boolean(布 爾 變 量),Character or String(字 符 或 字 符 串)。 integer 整 數 下 邊 給 出 的 數 據 表 示 都 是 整 數 的 例 子: 4 , 15 , 089 , 0xAD00 整 數 長 度 數 據 類 型 表 示 8 bits byte 16 bits short 32 bits int 64 bits long floating 浮點 數 下 邊 給 出 的 數 據 表 示 都 是浮點 數 的 例 子: 6.37 , 3.7E15 , 3e8 浮點 數 長 度 數 據 類 型 表 示 32 bits float 64 bits double Boolean 布 爾 變 量 下 邊 是 布 爾 變 量 的 兩 種 可 能 取 值: true false Character 字 符 下 邊 給 出 的 都 是 字 符 的 例 子: a \\t (tab) \\u????(unicode) String 字 符 串 下 邊 給 出 的 都 是 字 符 串 的 例 子: \"This is a string literal\" \"中 國 科 學 院 計 算 所\" 數 組 你 可 以 定 義 任 意 類 型 的 數 組. char s[]; 這 是 字 符 型 數 組; int [] array; 這 是 整 型 數 組; 你 還 可 以 定 義 數 組 的 數 組. int block[][]=new int [2][3]; 數 組 邊 界 在 運 行 時 被 檢 測,避 免 堆 棧 溢 出 和 內 存 崩 潰. 在Java里,數 組 實 際 上 是 一 個 對 象,數 組 有 一 個 成 員 變 量:length。 你 可 以 用 這 個 成 員 函 數 來 查 看 任 意 數 組 的 長 度. int a[][] = new int [10][3] a.length /* 10 */ a[0].length /* 3 */ 創 建 數 組 在Java里 創 建 數 組,你 可 使 用 兩 種 基 本 方 法 : 一。 創 建 一 個 空 數 組: int list[]=new int[50]; 或 你 可 以 用 初 始 數 值 填 充 數 組. String names[] = { \"Chenji\",\"Yuan\",\"Chun\",\"Yang\" }; 相 當 于 下 面 功 能: String names[]; names = new String[4]; names[0]=new String(\"Chenji\"); names[1]=new String(\"Yuan\"); names[2]=new String(\"Chun\"); names[3]=new String(\"Yang\"); 在 編 譯 時 你 不 能 象 下 例 那 樣 創 建 靜 態 數 組。 int name[50];//將 產 生 一 個 編 譯 錯 誤 你 也 不 能 用new操 作 去 填 充 一 個 沒 定 義 大 小 的 數 組。 int name[]; for (int i=0;i<9;i++) { name[i] = i; } 3.1.5 表 達 式 Java語 言 的 表 達 式 和C語 言 非 常 類 似。 運 算 符 運 算 符(operator)優 先 級 從 高 到 底 排 列 如 下: . [ ] () ++ -- ! ~ instanceof * / % + - << >> >>> < > <= >\\ == ! = & ^ && || ? :
= op = , 整 數 運 算 符 在 整 數 運 算 時, 如 果 操 作 數 是long類 型, 則 運 算 結 果 是long類 型, 否 則 為int類 型, 絕 不 會 是byte,short或char型。 這 樣, 如 果 變 量i被 聲 明 為short或byte,i+1的 結 果 會 是int。 如 果 結 果 超 過 該 類 型 的 取 值 范 圍, 則 按 該 類 型 的 最 大 值 取 模。 單 目 整 數 運 算 符 是: 運 算 符 操 作 - 單 目 非 ~ 位 補 碼 ++ 加1 -- 減1 ++運 算 符 用 于 表 示 直 接 加1操 作。 增 量 操 作 也 可 以 用 加 運 算 符 和 賦 值 操 作 間 接 完 成。++ lvalue (左 值?copy; 表 示lvalue+=1, ++lvalue 也 表 示lvalue =lvalue +1 (只 要lvalue沒 有 副 作 用)。--運 算 符 用 于 表 示 減1操 作。++和--運 算 符 既 可 以 作 為 前 綴 運 算 符, 也 可 以 做 為 后 綴 運 算 符。 雙 目 整 數 運 算 符 是: 運 算 符 操 作** + 加 - 減 * 乘 / 除 % 取 模 & 位 與 | 位 或 ^ 位 異 或 << 左 移 >> 右 移(帶 符 號) >>> 添 零 右 移 整 數 除 法 按 零 舍 入。 除 法 和 取 模 遵 守 以 下 等 式: ( a/b ) * b + ( a%b ) == a 整 數 算 術 運 算 的 異 常 是 由 于 除 零 或 按 零 取 模 造 成 的。 它 將 引 發 一 個 算 術 異 常。 下 溢 產 生 零, 上 溢 導 致 越 界。 例 如: 加1超 過 整 數 最 大 值, 取 模 后, 變 成 最 小 值。 一 個op=賦 值 運 算 符, 和 上 表 中 的 各 雙 目 整 數 運 算 符 聯 用, 構 成 一 個 表 達 式。 整 數 關 系 運 算 符<, >,<=,>=,==和!=產 生boolean類 型 的 數 據。 布 爾 運 算 符 布 爾(boolean)變 量 或 表 達 式 的 組 合 運 算 可 以 產 生 新 的boolean值。 單 目 運 算 符!是 布 爾 非。 雙 目 運 算 符 &, | 和^是 邏 輯AND,OR和XOR運 算 符, 它 們 強 制 兩 個 操 作 數 求 布 爾 值。 為 避 免 右 側 操 作 數 冗 余 求 值, 用 戶 可 以 使 用 短 路 求 值 運 算 符 & & 和 | |。 用 戶 可 以 使 用==和!=, 賦 值 運 算 符 也 可 以 用 &=、|=、^=。 三 元 條 件 操 作 符? : 和C語 言 中 的 一 樣。 浮點 運 算 符 浮點 運 算 符 可 以 使 用 常 規 運 算 符 的 組 合: 如 單 目 運 算 符++、--, 雙 目 運 算 符+、-、* 和/, 以 及 賦 值 運 算 符+=,-=,*=, 和/=。 此 外, 還 有 取 模 運 算: %和%=也 可 以 作 用 于浮點 數, 例 如: a%b和a-((int) (a/b)*b)的 語 義 相 同。 這 表 示a%b的 結 果 是 除 完 后 剩 下 的浮點 數 部 分。 只 有 單 精 度 操 作 數 的浮點 表 達 式 按 照 單 精 度 運 算 求 值, 產 生 單 精 度 結 果。 如 果浮點 表 達 式 中 含 有 一 個 或 一 個 以 上 的 雙 精 度 操 作 數, 則 按 雙 精 度 運 算, 結 果 是 雙 精 度浮點 數。 數 組 運 算 符 數 組 運 算 符 形 式 如 下: [ ] 可 給 出 數 組 中 某 個 元 素 的 值。 合 法 的 取 值 范 圍 是 從0到 數 組 的 長 度 減1。 取 值 范 圍 的 檢 查 只 在 運 行 時 刻 實 。 運 算 符 以String對 象 實 現。 運 算 符\"+\"完 成 并 操 作, 如 果 必 要 則 自 動 把 操 作 數 轉 換 為String型。 如 果 操 作 數 是 一 個 對 象, 它 可 定 義 一 個 方 法toString ( ) 返 回 該 對 象 的String方 式, 例 如 float a = 1.0 print (\"The value of a is\"+ a +\"\\n\"); +運 算 符 用 到 ?reg; 上 的 例 子 String s=\"a=\"+ a; +=運 算 符 也 可 以 用 于String。 注 意, 左 邊(下 例 中 的s1)僅 求 值 一 次。 s1+=a; //s1=s1+a //若a非String型, 自 動 轉 換 為String型。 對 象 運 算 符 雙 目 運 算 符instanceof 測 試 某 個 對 象 是 否 是 指 定 類 或 其 子 類 的 實 例。 例 如: if(myObject instanceof MyClass) { MyClass anothermyObject=( MyClass) myObject; … } 是 判 定myObject是 否 是MyClass的 實 例 或 是 其 子 類 的 實 例。 強 制 和 轉 換 Java語 言 和 解 釋 器 限 制 使 用 強 制 和 轉 換, 以 防 止 出 錯 導 致 系 統 崩 潰。 整 數 和浮點 數 之 間 可 以 來 回
強 制 轉 換, 但 整 數 不 能 強 制 轉 換 成 數 組 或 對 象。 對 象 不 能 被 強 制 為 基 本 類 型。 3.1.6 Java流 控 制 下 面 幾 個 控 制 結 構 是 從C語 言 借 鑒 的。 分 支 結 構 if/else分 支 結 構 if (Boolean) { statemanets; } else { statements; } switch分 支 結 構 switch(expr1) { case expr2: statements; break; case expr3: statements; break; default: statements; break; } 循 環 結 構 for循 環 結 構 for (init expr1;test expr2;increment expr3) { statements; } While循 環 結 構 While(Boolean) { statements; } Do循 環 結 構 do { statements; } while (Boolean); 一 般 順 序 控 制 break [label] continue [label] reutrn expr; label:statement; for循 環 例 子 下 面 是 一 個 程 序 例 子, 畫 幾 條 線, 分 別 用 紅,綠,藍 顏 色, 這 段 程 序 可 能 是Java函 數 的 一 部 分: int count; for (count=1;count<=12;count++) { switch (count % 3) } case 0: setColor(Color.red); break; case 1: setColor(Color.blue); break; case 2: setColor(Color.green); break; } g.drawLine(10,count*10,80,count*10); } 3.2 Java變 量 和 函 數 的 實 例 Java的 類 包 含 變 量 和 函 數。 數 據 變 量 可 以 是 一 些 原 始 的 類 型,如int,char等。 成 員 函 數 是 一 些 可 執 行 的 過 程。 例 如,下 面 程 序 里: public class ClassOne { int i; public ClassOne() { i=10; } public void Add_i(int j) { i=i+j; } } ClassOne包 含 一 個 變 量i和 兩 個 成 員 函 數,ClassOne(int first)和Add_i(int j)。 成 員 函 數 成 員 函 數 是 一 些 可 被 其 它 類 或 自 己 類 調 用 的 處 理 子 程 序。 一 個 特 殊 的 成 員 函 數 叫 構 造 函 數, 這 個 函 數 名 稱 一 般 與 本 類 名 程 相 同。 它 沒 有 返 回 值。 構 造 函 數 和 成 員 函 數 當 你 在Java里 定 義 一 個 類 時,你 可 定 義 一 個 或 多 個 可 選 的 構 造 函 數,當 創 建 本 類 的 一 個 對 象 時 用 某 一 個 構 造 函 數 來 初 始 化 本 對 象。 用 前 面 的 程 序 例 子 來 說 明,當ClassOne類 創 建 一 個 新 實 例 時, 所 有 成 員 函 數 和 變 量 被 創 建(創 建 實 例)。 構 造 函 數 被 調 用。 ClassOne mc: mc = new ClassOne(); 關 鍵 詞new用 來 創 建 一 個 類 的 實 例,一 個 類 用new初 始 化 前 并 不 占 用 內 存,它 只 是 一 個 類 型 定 義, 當mc對 象 初 始 化 后,mc對 象 里 的i變 量 等 于10。 你 可 以 通 過 對 象 名 來 引 用 變 量i。(有 時 稱 為 實 例 變 量) mc.i++;//mc實 例 變 量 加1 因 為mc有ClassOne類 的 所 有 變 量 和 成 員 函 數, 我 們 可 以 使 用 同 樣 的 語 法 來 調 用 成 員 函 數 Add_i: Add_i(10); 現 在mc.i變 量 等 于21. 結 束 函 數 Java并 不 支 持 析 構 函 數(C++里 的 定 義),因 為java本 身 提供 對 象 無 用 時 自 動 清 除 的 功 能,同 時 它 也 提 供了 一 個 自 動 拉 圾 箱 的 成 員 函 數, 在 清 除 對 象 時 被 調 用: Protected void finalize() { close(); } 3.3 對 象 有 效 范 圍 和 廢 物 自 動 回 收 對 象 有 一 定 的 生 命 期 并 在 它 的 生 命 期 間 使 用 資 源,當 一 個 對 象 不 再 被 使 用 時,它 應 釋 放 內 存, 避 免 內 存 溢 出。 在Java里,收 集 和 釋 放 內 存 是 一 個 叫 自 動 廢 品 回 收 站 的 線 程 的 責 任。 這 個 線 程 監 視 對 象 有 效 范 圍 并 給 一 個 走 出 有 效 范 圍 的 對 象 作 上 標 識。 例 如: String s;//沒 有 分 配 內 存 s = new String(\"oldstring\");//分 配 內 存 s =\"newstring\";//重 新 分 配 內 存(創 建 新 對 象) 我 們 將 在 以 后 訪 問String類 時 將 更 加 明 白 它 的 工 作 過 程,但 它 的 快 速 工 作 過 程 是 這 樣 的: 1.創 建 一 個 新 的String類 對 象 并 填 充 以\"oldstring\" 2.創 建 另 一 個String對 象 并 填 充 以\"newstring\" 注 意 我 們 創 建 了 兩 個 對 象。 Stirng 對 象 \"oldstring\" Stirng 對 象 \"newstring\" 在 第 三 條 語 句 里,第 一 個 包 括\"oldstring\"的 叫 做s的 對 象 已 走 出 了 有 效 范 圍,沒 有 任 何 方 法 可 以 再 訪 問 他,我 們 現 在 有 一 個 新 的 對 象 也 叫s,包 含\"newstring\"。 在 下 一 個 廢 品 回 收 線 程,前 一 個 對 象 將 被 標 識 并 清 除。 3.4 子 類 子 類 是 利 用 存 在 的 對 象 創 建 一 個 新 對 象 的 機 制,比 如,如 果 你 有 一 個Horse類,你 可 以 創 建 一 個 Zebra子 類,Zebra是Horse的 一 種。 class Zebra extends Horse { int number_OF_stripes: } 關 鍵 詞extends來 定 義 對 象 有 的 子 類.Zebra是Horse的 子 類。Horse類 里 的 所 有 特 征 都 將 拷 貝 到 Zebra類 里,而Zebra類 里 可 以 定 義 自 己 的 成 員 函 數 和 實 例 變 量。Zebra稱 為Horse的 派 生 類 或 繼 承。 另 外,你 也 許 還 想 覆 蓋 基 類 的 成 員 函 數。 用ClassOne說 明,下 面 是 一 個 派 生 類 覆 蓋Add_i功 能 的 例 子.
import ClassOne; public class NewClass extends ClassOne { public void
Add_i(int j) { i=i+(j/2); } } 當NewClass類 的 實 例 創 建 時,變 量i初 始 化 值 為10,但 調 用Add_i產 生 不 同 的 結 果。 NewClass mnc; mnc=new NewClass(); mnc.Add_i(10); 訪 問 控 制 Java里 當 你 創 建 一 個 新 類 時,你 可 以 標 明 變 量 和 成 員 函 數 的 訪 問 層 次。 public public void AnyOneCanAccess(){} public實 例 變 量 和 成 員 函 數 可 以 任 意 其 它 類 調 用。 protected protected void OnlySubClasses(){} protected實 例 變 量 和 成 員 函 數 只 能 被 其 子 類 調 用. private private String CreditCardNumber; private實 例 變 量 和 成 員 函 數 只 能 在 本 類 里 調 用. friendly void MyPackageMethod(){} 缺 省 的,如 果 沒 有 定 義 任 何 防 火 控 制,實 例 變 量 或 函 數 缺 省 定 義 成friendly,意 味 著 可 以 被 本 包 里 的 任 意 對 象 防 問,但 其 它 包 里 的 對 象 不 可 防 問。 靜 態 成 員 函 數 和 變 量 有 ?copy; 時 候,你 創 建 一 個 類,希 望 這 個 類 的 所 有 實 例 都 公 用 一 個 變 量。 也 就 是 說,所 有 這 個 類 的 對 象 都 只 有 實 例 變 量 的 同 一 個 拷 貝。 這 種 方 法 的 關 鍵 詞 是static, 例 如: class Block { static int number=50; }
所 有 從Block類 創 建 的 對 象 的number變 量 值 都 是 相 同 的。 無 任 在 哪 個 對 象 里 改 變 了number的 值, 所 有 對 象 的number都 跟 著 改 變。 同 樣 的,你 可 以 定 義static成 員 函 數,但 這 個 成 員 函 數 不 能 訪 問 非static函 數 和 變 量。 class Block { static int number = 50; int localvalue; static void add_local(){ localvalue++;//沒 有 運 行 } static void add_static() { number++;//運 行 } } 3.5 this和super 訪 問 一 個 類 的 實 例 變 量 時,this關 鍵 詞 是 指 向 這 個 類 本 身 的 指 針,在 前 面ClassOne例 子 中,我 們 可 以 增 加 構 造 函 數 如 下: public class ClassOne { int i; public ClassOne() { i = 10; } public ClassOne (int value) this.i = value; } public void Add_i(int j) { i = i + j; } } 這 里,this指 向ClassOne類 的 指 針。 如 果 在 一 個 子 類 里 覆 蓋 了 父 類 的 某 個 成 員 函 數,但 又 想 調 用 父 類 的 成 員 函 數,你 可 以 用super 關 鍵 詞 指 向 父 類 的 成 員 函 數。
import ClassOne; public class NewClass extends ClassOne { public void Add_i (int j) { i = i+(j/2); super.Add_i (j); } } 下 面 程 序 里,i變 量 被 構 造 函 數 設 成10,然 后15, 最 后 被 父 類(ClassOne)設 成25。 NewClass mnc; mnc = new NewClass(); mnc.Add_i(10); 3.6 類 的 類 型 至 今 為 止,我 用 在 類 前 面 只 用 了 一 個public關 鍵 詞,其 實 它 有 下 面4種 選 擇:abstract 一 個abstract類 必 須 至 少 有 一 個 虛 擬 函 數,一 個abstract類 不 能 直 接 創 建 對 象,必 須 繼 承 子 類 后 才 能。 final 一 個final類 聲 明 了 子 類 鏈 的 結 尾,用final聲 明 的 類 不 能 再 派 生 子 類。 public public類 能 被 其 它 的 類 訪 問。 在 其 它 包 里,如 果 想 使用 這 個 類 必 須 先import, 則 它 只 能 在 它 定 義 的package里 使 用。 synchronicable 這 個 類 標 識 表 示 所 有 ?copy; 類 的 成 員 函 數 都 是 同 步 的。 3.7 抽 象 類 面 向 對 象 的 一 個 最 大 優 點 就 是 能 夠 定 義 怎 樣 使 用 這 個 類 而 不 必 真 正 定 義 好 成 員 函 數。 如 果 程 序 由 不 同 的 用 戶 實 現 時 是 很 有 用 的, 這 不 需 用 戶 使 用 相 同 的 成 員 函 數 名。 在java里Graphics類 里 一 個abstract類 的 例 子 如 下: public abstract class Graphics { public abstract void drawLine(int x1,int y1,int x2, int y2); public abstract void drawOval(int x,int y,int width, int height); public abstract void drawRect(int x,int y,int width, int height); ... } 在Graphics類 里 聲 明 了 幾 個 成 員 函 數,但 成 員 函 數 的 實 際 代 碼 是 在 另 外 一 ?copy; 地 方 實 現 的。 public class MyClass extends Graphics { public void drawLine (int x1,int y1,int x2,int y2) { <畫 線 程 序 代 碼> } } 當 一 個 類 包 含 一 個abstract成 員 函 數,這 個 類 必 須 定 義 為abstract類。 然 而 并 不 是abstract類 的 所 有 的 成 員 函 數 都 是abstract的。Abstract類 不 能 有 私 有 成 員 函 數(它 們 不 能 被 實 現),也 不 能 有 靜 態 成 員 函 數。 3.8 接 口 當 你 確 定 多 個 類 的 操 作 方 式 都 很 相 象 時,abstract成 員 函 數 是 很 有 用 的。 但 如 果 你 需 要 使 用 這 ?copy;abstract成 員 函 數, 必 須 創 建 一 個 新 類, 這 樣 有 時 很 繁 瑣。 接 口 提 ?copy; 了 一 種 抽 象 成 員 函 數 的 有 利 方 法。 一 個 接 口 包 含 了 在 另 一 個 地 方 實 現 的 成 員 函 數 的 收 集。 成 員 函 數 在 接 口 里 定 義 為public和 abstract。 接 口 里 的 實 例 變 量 是public,static和final。 接 口 和 抽 象 的 主 要 區 別 是 一 個 接 口 提 ?copy; 了 封 裝 成 員 函 數 協 議 的 方 法 而 不 必 強 迫 用 戶 繼 承 類。 例 子: public interface AudiClip { //Start playing the clip. void play(); //Play the clip in a loop. void loop(); //Stop playing the clip void stop(); } 想 使 用Audio Clip接 口 的 類 使 用implenents關 鍵 詞 來 提 ?copy; 成 員 函 數 的 程 序 代 碼。 class MyClass implements AudioClip { void play(){ <實 現 代 碼> } void loop <實 現 代 碼> } void stop <實 現 代 碼> } } 優 點 一 個 接 口 類 可 以 被 任 意 多 的 類 實 現, 每 個 類 可 以 共 享 程 序 接 口 而 不 必 關 心 其 它 類 是 怎 樣 實 現 的。 class MyOtherClass implements AudioClip { void stop(){ <實 現 代 碼> } ... } 內 部 成 員 函 數 Java還 提 ?copy; 了 調 用C和C++函 數 的 方 法。 用native關 鍵 詞 來 定 義C和C++的 函 數。 public class Date { int now; public Date() { now = time (); } private native int time (); static { System.loadLibrary(\"time\"); } } 一 ?copy;Java代 碼 寫 好 后,就 需 要 以 下 步 驟 執 行: 1.用javah來 創 建 頭 文 件(.h) 2.用javah來 創 建stub文 件 3.用C和C++寫native成 員 函 數 的 代 碼 4.編 譯stub文 件 和.C文 件 成 一 個 動 態 可 加 載 庫 5.用java運 行java程 序 或appletviewer運 行applet 注 意:Native成 員 函 數 超 出 了 類 的 范 圍。 3.9 包(Packages) 包(Package)由 一 組 類(class)和 界 面(interface)組 成。 它 是 管 理 大 型 名 字 空 間, 避 免 名 字 沖 突 的 工 具。 每 一 個 類 和 界 面 的 名 字 都 包 含 在 某 個 包 中。 按 照 一 般 的 習 慣, 它 的 名 字 是 由\".\" 號 分 隔 的 單 詞 構 成, 第 一 個 單 詞 通 常 是 開 發 這 個 包 的 組 織 的 名 稱。 定 義 一 個 編 譯 單 元 的 包 編 譯 單 元 的 包 由package語 句 定 義。 如 果 使 用package語 句, 編 譯 單 元 的 第 一 行 必 須 無 空 格, 也 無 注 釋。 其 格 式 如 下: package packageName; 若 編 譯 單 元 無package語 句, 則 該 單 元 被 置 于 一 個 缺 省 的 無 名 的 包 中。 使 用 其 它 包 中 的 類 和 界 面 在Java語 言 里 提 ?copy; 一 個 包 可 以 使 用 另 一 個 包 中 類 和 界 面 的 定 義 和 實 現 的 機 制。 用import關 鍵 詞 來 標 明 來 自 其 它 包 中 的 類。 一 個 編 譯 單 元 可 以 自 動 把 指 定 的 類 和 界 面 輸 入 到 它 自 己 的 包 中。 在 一 個 包 中 的 代 碼 可 以 有 兩 種 方 式 來 定 義 來 自 其 它 包 中 的 類 和 界 面: * 在 每 個 引 用 的 類 和 界 面 前 面 給 出 它 們 所 在 的 包 的 名 字; //前 綴 包 名 法 acme. project.FooBar obj=new acme. project. FooBar( ); * 使 用import語 句, 引 入 一 個 類 或 一 個 界 面, 或 包 含 它 們 的 包。 引 入 的 類 和 界 面 的 名 字 在 當 前 的 名 字 空 間 可 用。 引 入 一 個 包 時, 則 該 包 所 有 的 公 有 類 和 界 面 均 可 用。 其 形 式 如 下: // 從 acme.project 引 入 所 有 類 import acme.project.*; 這 個 語 句 表 示acme.project中 所 有 的 公 有 類 被 引 入 當 前 包。 以 下 語 句 從acme. project包 中 進 入 一 個 類Employec_List。 //從 acme. project而 引 入 Employee_List import acme.project.Employee_list; Employee_List obj = new Employee_List( ); 在 使 用 一 個 外 部 類 或 界 面 時, 必 須 要 聲 明 該 類 或 界 面 所 在 的 包, 否 則 會 產 生 編 譯 錯 誤。 import(引 用) 類 包(class package)用import關 鍵 詞 調 入,指 定package名 字 如 路 徑 和 類 名,用*匹 配 符 可 以 調 入 多 于 一 個 類 名。
import java.Date; import java.awt.*; 如 果java源 文 件 不 包 含package,它 放 在 缺 省 的 無 名package。 這 與 源 文 件 同 目 錄, 類 可 以 這 樣 引 入: import MyClass。 Java系 統 包: Java語 言 提 ?copy; 了 一 個 包 含 窗 口 工 具 箱, 實 用 程 序, 一 般I/O,工 具 和 網 絡 功 能 的 包。 java.applet 這 個 包 包 含 量 了 一 ?copy; 設 計applet的 類,用 一 個 類Applet和 三 個 接 口. AppletContext;AppletStub;和AudioClip. java.awt 另 一 個 窗 口 工 具 箱 包.awt,包 含 了 一 ?copy; 產 生 裝 飾 物 和GUI成 員 的 類。 這 個package包 括: Button,Checkbox,Choice,Component,Graphics,Menu,Pane1,TextArea和 TextField。 java.io I/O package包 含 文 件 輸 入/輸 出 類,FileInput Stream和File OutputStream. java.lang 這 個 包 包 含Java語 言 類,包 含:對 象,線 程,異 常 出 口,系 統,整 數,原 點,數 學,字 符 等。 java.net 這 個 類 支 持TCP/IP網 絡 協 議, 并 包 含Socket類,URL和URL相 聯 系 的 類。 java.util 這 個 類 包 含 一 ?copy; 程 序 的 同 步 類,它 包 含Date,Dictionary類 等。 3.10 異 常 當 在Java程 序 中 發 生 一 個 錯 誤 時, 例 如: 一 個 變 元 的 值 非 法, 代 碼 會 發 現 這 個 錯 誤, 并 引 發 一 個 異 常(exception)。 在 缺 省 的 情 況 下, 異 常 會 輸 出 一 個 錯 誤 消 息, 然 后 中 止 線 程 的 執 行。 但 是, 程 序 自 己 可 以 定 義 異 常 處 理 段(exception handler)來 截 獲(catch)異 常, 并 從 錯 誤 中 恢 復。 有 一 ?copy; 異 常 是 由Java解 釋 器 在 運 行 時 刻 引 發 的。 實 際 上, 任 何 類 都 可 以 定 義 屬 于 自 己 的 異 常, 并 使 用throw語 句 引 發 它 們。 一 個throw(引 發?copy; 語 句 是 由throw關 鍵 字 和 一 個 對 象 構 成。 按 常 規, 該 對 象 應 該 是Exception 類 的 實 例 或 其 子 類 的 實 例。throw語 句 會 引 起 執 行 轉 向 相 應 的 異 常 處 理 段。 當 一 個throw語 句 執 行 時, 它 下 面 的 所 有 代 碼 不 再 執 行 了, 它 所 在 的 方 法 也 不 再 返 回 值。 下 面 的 例 子 將 演 示 如 何 創 建 一 個Exception的 子 類, 然 后 引 發 一 個 異 常。 class MyException extends Exception { } class MyClass { void oops() { if ( /* 不 出 現 錯 誤 */) { … } else { /* 出 錯 */ } else { /* 出 錯 */ throw new MyException( ); } } } 為 了 定 義 一 個 異 常 處 理 段, 程 序 必 須 用try語 句 把 可 能 產 生 異 常 的 代 碼 成 組。 在try語 句 后 面 跟 上 一 個 或 多 個catch(截 獲?copy; 語 句, 每 個 異 常 對 應 一 個catch語 句。 每 個catch語 句 中 包 含 著 異 常 處 理 段。 例 如: try { p.a=10; } catch ( NullPointerException e) { println(\"p was null\"); } catch ( Exception e) { println (\"other errors occured\"); } catch ( Object obj) { println(\"Who threw that object?\"); } catch語 句 和 一 個 方 法 定 義 類 似, 只 不 過 該 方 法 只 有 一 個 參 數, 且 無 返 回 類 型。 參 數 可 以 是 一 個 類 或 一 個 界 面。 當 一 個 異 常 發 生 時, 嵌 套 的try/catch語 句 會 尋 找 出 與 該 異 常 類 相 匹 配 的 參 數。 如 果 一 個 參 數 和 指 定 異 常 匹 配 則: * 該 參 數 和 指 定 的 異 常 是 同 一 個 類, 或 * 該 參 數 是 指 定 異 常 的 子 類, 或 * 如 果 參 數 是 一 個 界 面, 指 定 異 常 類 實 現 了 這 個 界 面。 第 一 個 參 數 和 異 常 匹 配 的try/catch語 句, 則 與 其 匹 配 的catch語 句 執 行。 在catch語 句 執 行 完 后, 程 序 的 執 行 被 恢 復。 但 已 不 可 能 恢 復 到 異 常 發 生 處 再 次 執 行。 例 如: print ( \"now\"); try { print (\"is\"); throw new MyException( ); print (\"a\"); } catch (MyException e) { print (\"the \"); } print (\"time\\n\"); 打 印 為\"now is the time\"。 正 如 這 個 例 子 所 示, 異 常 應 該 主 要 用 于 錯 誤 處 理, 若 用 于 其 它 方 面 會 使 代 碼 晦 澀 難 ?reg;。 異 常 處 理 段 是 可 以 嵌 套 的, 允 許 異 常 處 理 可 以 發 生 在 多 個 地 方。 嵌 套 異 常 處 理 通 常 用 于 當 第 一 個 處 理 程 序 無 法 完 全 從 錯 誤 中 恢 復 過 來 的 時 候, 而 不 得 不 執 行 一 ?copy; 清 除 代 碼。 為 了 把 異 常 處 理 控 制 傳 遞 給 更 高 層 的 處 理 段, 可 以 再 一 次 對 截 獲 對 象 實 ?copy;throw操 作。 注 要 再 次 實 throw異 常 的 方 法,throw語 句 執 行 完 后, 會 終 止 執 行。 try { f. open ( ); } catch(Exception e) { f. close( ); throw e; } 定 局 語 句 finally(定 局?copy; 語 句 是 用 于 保 證 無 論 在 異 常 是 否 發 生 的 情 況 下, 某 ?copy; 代 碼 被 執 行。 下 例 說 明finally語 句 的 用 法: try { //做 某 ?copy; 動 作; } finally { //此 后 清 除; } 和 以 下 代 碼 類 似 try { //做 某 ?copy; 動 作 } catch (Object e) { //此 后 清 除; throw e; } } //此 后 清 除; 即 使try塊 中 包 含return,break,continue,throw語 句,finally語 句 也 會 被 執 行。 例 如: 下 面 的 代 碼\"finally\" 總 是 被 輸 出, 而\"aftertry\" 僅 在a!=10時 被 輸 出。 try { if (a==10) { return ; } } finally { print (\"finally\\n\"); } print (\"after try \\n\"); 運 行 時 刻 異 常 本 節 列 出 的 清 單 是Java解 釋 器 引 發 的 各 種 異 常。 當 運 行 時 刻 發 現 各 種 錯 誤, 由 解 釋 器 引 發 異 常。 ArithmeticException 如 果 程 序 試 圖 除0, 或 用0取 模, 會 產 生ArithmeticException(算 術 異 常?copy;, 其 它 算 術 操 作 不 會 產 生 異 常。 有 關Java如 何 處 理 其 它 算 術 錯 誤 的 信 息, 見\" 整 數 運 算 符\" 和\"浮點 運 算 符\" 兩 節。 例 如: 下 面 的 代 碼 將 會 引 發ArithmeticException異 常: class Arith { public static void main (String args [ ] ) { int j = 0; j = j/j; } } NullPointerException 當 程 序 試 圖 訪 問 一 個 空 對 象 中 的 變 量 或 方 法, 或 一 個 空 數 組 中 的 元 素 時 則 引 發 NullPointerException(空 指 針 異 常?copy;。 例 如, 訪 問 長 度 為0的 數 組a[0]。 有 以 下 類 聲 明, 運 行 時 會 引 發NullPointerException異 常: class Null { public static void main(String args [ ]) { String o = null; int a [ ] = null; o.length( ); a[0] = 0; } } 有 趣 的 是, 如 果 我 們 引 發 一 個 空 對 象, 也 會 產 一NullPointerException異 常。 IncompatibleClassChangeException 當 一 個 類 的 定 義 被 改 變, 而 引 用 該 類 的 其 它 類 沒 有 被 重 新 編 譯 時, 會 產 生 這 一 異 常。 有 四 種 類 更 改 會 導 致 運 行 時 刻 引 發IncompatibleClassChangException異 常。 * 一 個 類 中 的 變 量 聲 明 由static變 成 非static, 而 其 它 訪 問 該 類 這 一 變 量 的 類 沒 有 被 重 新 編 譯。 * 一 個 類 中 的 變 量 聲 明 由 非static變 成static, 而 其 它 訪 問 該 類 這 一 變 量 的 類 沒 有 被 重 新 編 譯。 * 類 中 聲 明 的 某 個 域 被 刪 除, 而 其 它 訪 問 該 域 的 類 沒 有 被 重 新 編 譯。 * 類 中 聲 明 的 某 個 方 法 被 刪 除, 而 其 它 訪 問 該 方 法 的 類 沒 有 被 重 新 編 譯。 ClassCastException 如 果 試 圖 把 對 象o強 制 成Class C, 而o既 不 是Class C的 實 例, 也 不 是Class C子 類 的 實 例, 這 時 便 會 產 生ClassCastException。 class ClassCast { public static void main (String args [ ] ) { Object o = new Object( ); String s = (string) o; s.length( ); } } } NagativeArraySizeException 如 果 一 個 數 組 的 長 度 是 負 數, 則 會 引 發NagativeArraySizeException(數 組 負 下 標?copy; 異 常。 例 如 下 面 類 定 義 的 代 碼 在 運 行 時 引 發 這 一 異 常: class NegArray { public static void main(String args [ ]) { int a [ ] = new int [-1]; a[0] = 0; } } OutOfMemoryException 當 系 統 無 法 再 向 應 用 程 序 提 ?copy; 內 存 時, 會 引 發OutOfMemoryException(內 存 溢 出?copy; 異 常。 這 種 異 常 只 能 出 現 在 創 建 新 對 象 的 時 候, 即new被 調 用 的 時 候。 例 如, 下 面 一 段 代 碼 在 運 行 時 刻 會 引 發OutOfMemoryException異 常: class Link { int a [ ] = new int [1000000]; Link l; } Class OutOfMem
{ public static void main(String args [ ]) { public static void main(String args [ ]) { Link root = new link( ); Link cur = root; while (true) { cur.l = new Link( ); cur = cur.l; } } } NoClassDefFoundException 如 果 一 個 類 被 引 用, 但 在 運 行 時 刻, 系 統 沒 有 找 到 被 引 用 的 類, 這 時 會 引 發 NoClassDefFoundException(未 找 到 類 定 義?copy; 異 常。 例 如,NoClass
的 聲 明 如 下: class NoClass { public static void main(String args [ ]) { C c = new C ( ); } } 當NoClass運 行 時, 如 果 解 釋 器 找 不 到C類, 則 會 產 生NoClassDefFoundException。 注 意, 在NoClass被 編 譯 時C類 一 定 要 存 在。 IncompatibleType Exception 如 果 試 圖 為 一 界 面 作 實 例, 則 會 引 發IncompatibleTypeException(類 型 不 兼 容?copy; 異 常。 例 如, 下 面 的 代 碼 會 引 發 一 個IncompatibleTypeException。 Interface I { } class IncompType { public static void main(String args [ ]) { I r = (I) new (\"I\"); } } ArrayIndexOutOfBoundsException 試 圖 訪 問 數 組 中 的 一 個 非 法 元 素 時, 會 引 發ArrayIndexOutOfBoundsException(數 組 索 引 越 界?copy; 異 常。 例 如: Class ArrayOut { public static void main(String args [ ]) { int a [ ]=new int[0]; a[0]=0; } } public static void main(String args [ ]) { int a [ ]=new int[0]; a[0]=0; } } UnsatisfiedLinkException 如 果 一 個 方 法 被 聲 明 為 本 機, 但 該 方 法 在 運 行 時 刻 卻 不 能 連 接 到 一 個 例 程 體 上 去 時, 會 產 生 UnsatisfiedLinkException(無 法 連 接?copy; 異 常。 例 如: Class NoLink { static native void foo( ); public static void main(String args [ ]) { foo( ); } } InternalException InternalException(內 部?copy; 異 常 是 不 能 被 引 發 的。 只 有 在 運 行 失 敗 作 一 致 性 檢 查 時, 才 會 引 發 這 個 異 常。 本 章 小 結 1. Java語 言 的 基 本 結 構 象C/C++。 2. Java語 言 的 源 程 序 代 碼 由 一 個 或 多 個 編 譯 單 元(compilation unit)組 成。
轉載于:https://blog.51cto.com/admijie/47117
總結
- 上一篇: xp上使用文件夹的共享和安全
- 下一篇: Java多线程初学者指南(12):使用S