1、1. 编 写 程 序 , 用 数 组 实 现 乘 法 小 九 九 的 存 储 和 输 出 。 【 提 示 : 采 用 多 个 一 维 数 组 。 】publicclassMultipationpublicstaticvoidmain(Stringargs)/TODOAuto-generatedmethodstubintx=newint99;for(inti=0;i=j)intm=i+1;intn=j+1;xij=m*n;System.out.print(m+“*“+n+“=“+xij);System.out.println();2. 定 义 一 个 类 Student, 属 性 为 学 号 、
2、 姓 名 和 成 绩 ; 方 法 为 增 加 记 录 SetRecord 和 得 到 记 录GetRecord。 SetRecord 给 出 学 号 、 姓 名 和 成 绩 的 赋 值 , GetRecord 通 过 学 号 得 到 考 生 的 成 绩 。publicclassStudent/*paramargs*/privateintID;privateStringname;privatefloatscore;publicvoidSetRecord(intID,Stringname,floatscore)this.ID=ID;this.name=name;this.score=score;p
3、ublicfloatgetRecord(intID)if(ID=this.ID)returnthis.score;elsereturn-1;publicstaticvoidmain(Stringargs)/TODOAuto-generatedmethodstubStudents=newStudent();s.SetRecord(0,“alex“,100);floatSco=s.getRecord(0);System.out.print(Sco);3. 给 出 上 题 中 设 计 类 的 构 造 函 数 , 要 求 初 始 化 一 条 记 录 (学 号 、 姓 名 、 成 绩 )。4.publi
4、cclassStudent5.6./*7.*paramargs8.*/9.privateintID;10.privateStringname;11.privatefloatscore;12.13.Student(intID,Stringname,floatscore)14.this.ID=0;15.this.name=“666“;16.this.score=65;17.18.publicvoidSetRecord(intID,Stringname,floatscore)19.this.ID=ID;20.this.name=name;21.this.score=score;22.23.publi
5、cfloatgetRecord(intID)24.if(ID=this.ID)25.returnthis.score;26.else27.return-1;28.29.30.publicstaticvoidmain(Stringargs)31./TODOAuto-generatedmethodstub32.Students=newStudent(0,“sdfs“,12);33./s.SetRecord(0,“alex“,100);34.floatSco=s.getRecord(0);35.System.out.print(Sco);36.37.4. 编 写 程 序 , 测 试 字 符 串 “你
6、 好 , 欢 迎 来 到 Java 世 界 ”的 长 度 , 将 字 符 串 的 长 度 转 换 成 字 符串 进 行 输 出 , 并 对 其 中 的 “Java”四 个 字 母 进 行 截 取 , 输 出 截 取 字 母 以 及 它 在 字 符 串 中 的 位 置 。publicclassStringTest/*paramargs*/publicstaticvoidmain(Stringargs)/TODOAuto-generatedmethodstubStringstr=“你 好 , 欢 迎 来 到Java世 界“;intlength=str.length();charstringArr=
7、str.toCharArray();/System.out.print(stringArr);for(inti=0;ilength;i+)/System.out.print(stringArri);/System.out.print(stringArr0);if(J=stringArri)System.out.print(i);1. 自 己 设 计 一 个 坐 标 类 , 能 提 供 以 下 方 法 如 求 当 前 坐 标 和 其 他 坐 标 之 间 的 距 离 等 方法 , 要 求 所 有 变 量 为 私 有 变 量 , 并 提 供 两 个 构 造 函 数 。publicclassXYdis
8、tanceprivateintx;privateinty;XYdistance()setX(0);setY(0);publicvoidsetX(intx)this.x=x;publicintgetX()returnx;publicvoidsetY(inty)this.y=y;publicintgetY()returny;publicstaticvoidmain(Stringargs)/TODOAuto-generatedmethodstubXYdistancem_1=newXYdistance();m_1.setX(10);m_1.setY(10);XYdistancem_2=newXYdis
9、tance();doubledistance=(m_1.getX()-m_2.getX()*(m_1.getX()-m_2.getX()+(m_1.getY()-m_2.getY()*(m_1.getY()-m_2.getY();doubleresult=Math.sqrt(distance);System.out.println(result);编 写 使 用 静 态 变 量 统 计 一 个 类 产 生 的 实 例 对 象 的 个 数 的 程 序 ?publicclassStaticprivatestaticintnumber;publicStatic()/number=number+1;+
10、number;/System.out.println(+number);publicstaticvoidmain(Stringargs)/TODOAuto-generatedmethodstubnewStatic();/m_1.Static();System.out.println(Static.number);创 建 string 对 象 过 程 的 内 存 分 配 :常 量 池 ( Constant Pool) : 指 的 是 在 编 译 期 被 确 定 , 并 被 保 存 在 已 编 译 的 .class文 件 中 的 一 些 数 据 。 JVM虚 拟 机 为 每 个 被 装 载 的 类
11、 型 维 护 一 个 常 量 池 。 常 量 池 就是 该 类 型 所 用 到 常 量 的 一 个 有 序 集 和 , 包 括 直 接 常 量 ( String,Integer和Floating point常 量 ) 和 对 其 他 类 型 , 字 段 和 方 法 的 符 号 引 用 。 对 于 String常量 , 它 的 值 是 在 常 量 池 中 的 。 而 JVM中 的 常 量 池 在 内 存 当 中 是 以 表 的 形 式 存 在 的 ,对 于 String类 型 , 有 一 张 固 定 长 度 的 CONSTANT_String_info表 用 来 存 储 文 字 字符 串 值 ,
12、 注 意 : 该 表 只 存 储 文 字 字 符 串 值 , 不 存 储 符 号 引 用 。1、 String s = “abc“;创 建 过 程 分 析 : 在 class文 件 被 JVM装 载 到 内 存 中 , JVM会 创 建 一 块 StringPool( String缓 冲 池 ) 。 当 执 行 String s = “ abc” ;时 , JVM首 先 在 String Pool中 查 看 是 否 存 在 字 符 串 对 象 “ abc” ( 如 何 查 看 呢 ? 用 equals()方 法 判 断 ) , 如果 已 存 在 该 对 象 , 则 不 用 创 建 新 的 字
13、符 串 对 象 “ abc” , 而 直 接 使 用 StringPool中 已 存 在 的 对 象 “ abc” , 然 后 将 引 用 s指 向 该 对 象 ; 如 果 不 存 在 该 对 象 , 则 先在 String Pool中 创 建 一 个 新 的 字 符 串 对 象 “ abc” , 然 后 将 引 用 s指 向 StringPool中 创 建 的 新 对 象 。注 意 : 使 用 “ 字 符 串 常 量 ” 引 号 创 建 的 字 符 串 对 象 时 , 在 编 译 期 就 已 经 确 定 将该 对 象 存 储 到 String Pool 中 了 。 因 此 , String
14、s = “ abc” 只 会 在 编 译 期 ,在 String Pool中 创 建 一 个 对 象 。例 如 :Java代 码1. String s1 = “abc“;2. String s2 = “abc“;3. System.out.println(s1 = s2);/true结 果 说 明 : JVM创 建 了 两 个 引 用 str1和 str2, 但 在 String Pool中 只 创 建 了 一个 对 象 , 而 且 两 个 引 用 都 指 向 了 同 一 个 对 象 。2、 String s = new String(“abc“);创 建 过 程 分 析 : 当 执 行 St
15、rings=newString(“ abc” );时 , JVM首 先 在 StringPool中 查 看 是 否 存 在 字 符 串 对 象 “ abc” , 如 果 不 存 在 该 对 象 , 则 先 在 StringPool中 创 建 一 个 新 的 字 符 串 对 象 “ abc” , 然 后 执 行 new String(“ abc” )构 造方 法 , 在 Heap里 又 创 建 一 个 新 的 字 符 串 对 象 “ abc” ( new出 来 的 对 象 都 放 在 Heap里 面 ) , 并 将 引 用 s指 向 Heap中 创 建 的 新 对 象 ; 如 果 已 存 在 该
16、 对 象 , 则 不 用 创建 新 的 字 符 串 对 象 “ abc” , 而 直 接 使 用 String Pool中 已 存 在 的 对 象 “ abc” ,然 后 执 行 new String(“ abc” )构 造 方 法 , 在 Heap里 又 创 建 一 个 新 的 字 符 串 对象 “ abc” , 并 将 引 用 s指 向 Heap中 创 建 的 新 对 象 。注 意 : 使 用 new String( “ ” ) 创 建 的 字 符 串 对 象 时 , 会 在 运 行 期 创 建 新 对 象存 储 到 Heap中 。 因 此 , new String( “ abc” ) 创
17、 建 字 符 串 对 象 时 , 会 创 建 2个 对 象 , 编 译 期 在 String Pool 中 创 建 一 个 , 运 行 时 Heap 中 创 建 一 个 。这 里 使 用 了Java代 码1. public String(String original)这 个 构 造 方 法 , 作 用 : 初 始 化 一 个 新 创 建 的 String 对 象 , 使 其 表 示 一 个 与 参 数相 同 的 字 符 序 列 ; 换 句 话 说 , 新 创 建 的 字 符 串 是 该 参 数 字 符 串 的 副 本 。由 于 Sring类 是 不 可 变 的 , 因 而 不 必 使 用 该
18、 构 造 方 法 , 除 非 需 要 original的 显式 副 本 。例 如 :Java代 码1. String s1 = new String(“abc“);2. String s2 = new String(“abc“);3. System.out.println(s1 = s2);/false结 果 说 明 : 只 要 是 用 new()来 新 建 对 象 的 , 都 会 在 堆 ( Heap) 中 创 建 , 而 且 其 字符 串 是 单 独 存 值 的 , 即 使 与 String Pool中 的 数 据 相 同 , 也 不 会 与 String Pool中 的 数 据 共 享
19、。例 程 1:Java代 码1. String s1 = “abcdef“;2. String s2 = “abcdef“;3. String s3 = “abc“+“def“;/编 译 期 自 动 优 化 为String s3 = “abcdef“;4. System.out.println(s1 = s2);5. System.out.println(s1 = s3);6. System.out.println(s2 = s3);运 行 结 果 :truetruetrue结 果 说 明 : 字 符 串 常 量 生 成 的 字 符 串 对 象 在 StringPool中 只 有 一 个 拷
20、贝 , 且 它是 在 编 译 期 就 被 确 定 了 , 所 以 “ s1=s2” ; “ abc” 和 “ def” 都 是 字 符 串 常 量 ,当 一 个 字 符 串 由 多 个 字 符 串 常 量 连 接 而 成 时 , 它 自 己 也 肯 定 是 字 符 串 常 量 ( 它 在编 译 期 就 被 解 析 为 一 个 字 符 串 对 象 了 , 即 class文 件 中 就 已 经 存 在 “ abcdef” ) ,所 以 在 字 符 串 生 成 字 符 串 对 象 时 , s3也 是 String Pool中 “ abcdef” 的 一 个 引用 。 故 JVM对 于 字 符 串 常
21、 量 的 “+“号 连 接 , 在 程 序 编 译 期 , JVM就 将 常 量 字 符 串的 “+“连 接 优 化 为 连 接 后 的 值 。例 程 2:Java代 码1. String s1 = “abc“;2. String s2 = “def“;3. String s3 = “abcdef“;4. String s4 = “abc“+“def“;5. String s5 = s1 + “def“;6. String s6 = “abc“+s2;7. String s7 = s1 + s2;8. System.out.println(s3 = s4);9. System.out.prin
22、tln(s3 = s5);10.System.out.println(s3 = s6);11.System.out.println(s3 = s7);运 行 结 果 如 下 :truefalsefalsefalse结 果 说 明 : JVM对 于 有 字 符 串 引 用 存 在 的 字 符 串 “+“连 接 中 , 而 引 用 的 值 在 程 序编 译 期 是 无 法 确 定 的 , 即 s1 + “ def” 无 法 被 编 译 器 优 化 , 只 有 在 程 序 运 行 期来 动 态 分 配 并 将 连 接 后 的 新 地 址 赋 给 s5。例 程 3:Java代 码1. final St
23、ring s1 = “abc“;2. String s2 = “def“;3. String s3 = “abcdef“;4. String s4 = “abc“+“def“;5. String s5 = s1 + “def“;6. String s6 = “abc“+s2;7. String s7 = s1 + s2;8. System.out.println(s3 = s4);9. System.out.println(s3 = s5);10.System.out.println(s3 = s6);11.System.out.println(s3 = s7);运 行 结 果 如 下 :tr
24、uetruefalsefalse例 程 4:Java代 码1. final String s1 = “abc“;2. final String s2 = “def“;3. String s3 = “abcdef“;4. String s4 = “abc“+“def“;5. String s5 = s1 + “def“;6. String s6 = “abc“+s2;7. String s7 = s1 + s2;8. System.out.println(s3 = s4);9. System.out.println(s3 = s5);10.System.out.println(s3 = s6);
25、11.System.out.println(s3 = s7);运 行 结 果 如 下 :truetruetruetrue结 果 说 明 : 例 程 3和 例 程 4与 例 程 2的 区 别 是 , 例 程 3在 字 符 串 s1前 加 了 final修 饰 , 例 程 4在 字 符 串 s1和 s2前 都 加 了 final修 饰 。 对 于 final修 饰 的 变 量 ,它 在 编 译 时 被 解 析 为 常 量 值 的 一 个 本 地 拷 贝 存 储 到 自 己 的 常 量 池 中 或 嵌 入 到 它的 字 节 码 流 中 。 所 以 此 时 的 s1 + “ def” 和 “abc“
26、+ “def“效 果 是 一 样 的 。 接 着后 面 两 个 含 引 用 的 字 符 串 连 接 , JVM会 进 行 相 同 的 处 理 。 故 上 面 程 序 后 面 三 个 的结 果 为 true。例 程 5:Java代 码1. public static void main(String args)2. String s1 = “abc“;3. final String s2 = getDef();4. String s3 = “abcdef“;5. String s4 = “abc“+s2;6. String s5 = s1 + s2;7. System.out.println(s
27、3 = s4);8. System.out.println(s3 = s5);9. Java代 码1. private static String getDef()2. return “def“;3. 程 序 运 行 结 果 如 下 :falsefalse结 果 说 明 : JVM对 于 方 法 调 用 给 字 符 串 引 用 赋 值 的 情 况 , 引 用 指 向 字 符 串 的 值 在编 译 期 是 无 法 确 定 的 , 只 有 在 程 序 运 行 调 用 方 法 后 , 将 方 法 的 返 回 值 “ def” 和“ abc” 动 态 连 接 并 分 配 新 地 址 赋 值 给 s4,
28、 所 以 上 述 程 序 的 结 果 都 为 false。通 过 以 上 的 例 子 可 知 :Java代 码1. String s = “a“ + “b“ + “c“;等 价 于 :Java代 码1. String s = “abc“;编 译 期 , 直 接 优 化 , 进 行 常 量 连 接 。对 于 :Java代 码1. String a = “a“;2. String b = “b“;3. String c = “c“;4. String s = a + b + c;就 不 等 价 于 : 等 价 于 :Java代 码1. String s = “abc“;最 终 结 果 等 于 :J
29、ava代 码1. StringBuilder builder = new StringBuilder ();2. builder.append(a);3. builder.append(b);4. builder.append(c);5. String s = builder.toString();去 看 StringBuilder的 toString()方 法 :Java代 码1. public String toString() 2. / Create a copy, dont share the array3. return new String(value, 0, count);4.
30、可 以 发 现 是 通 过 new String()返 回 了 一 个 String对 象 , 也 就 是 说 在 堆 中 创 建了 对 象 。 这 时 候 会 不 会 在 池 中 出 现 “abc“这 个 对 象 呢 ? ( question还 没 解 决 )生 成 String s的 过 程 中 , 编 译 器 使 用 sb执 行 的 过 程 : 创 建 一 个 StringBuffer对 象 , 使 用 append()向 此 StringBuffer对 象 直 接 添 加 新 的 字 符 串 ( 而 不 是 每 次制 作 一 个 新 的 副 本 ) 。对 于 String c = “c
31、“;String s = “a“ + “b“ + c;, 编 译 器 将 会 先 将 “a“ + “b“作 为 编 译 时 常 量 , 优 化 生 成 成 字 面 常 量 “ab“ , 然 后 生 成 一 个 StringBuilder 对象 , 接 着 调 用 两 次 append()方 法 , 即 :String s = new Builder().append(“ab“).append(c) .toString();对 于 String a = “a“;String s = a + “b“ + “c“;, 编 译 器 分 析 a为 引 用 变 量 ,后 面 的 “b“ + “c“就 不
32、会 作 为 编 译 时 常 量 来 运 算 了 。 相 当 于 执 行 :String s = new Builder().append(a).append(“b“) .append(“c“) .toString();对 于 String b = “b“;String s = “a“ + b + “c“;, 这 种 形 式 的 就 没 办 法 优 化了 , 直 接 生 成 StringBuilder 对 象 , 然 后 调 用 三 次 append()方 法 , 即 :String s = new Builder().append(“a“).append(b) .append(“c“) .to
33、String();接 着 , 我 们 再 看 以 下 代 码 :Java代 码1. String str1 = “abc“;/是 字 符 串 常 量 , 它 在 编 译 期 被 确 定 , 放 在 常量 池 中 ( 共 享 内 容 值 )2. /new String()创 建 的 字 符 串 不 放 入 常 量 池 中3. String str2 =new String(“abc“);/不 是 字 符 串 常 量 , 不 在 编 译 期 确定 ( 不 共 享 内 容 值 )Java代 码1. String str1 = new String(“abc“);2. String str2 = “a
34、bc“;3. System.out.println(str1=str2); /false创 建 了 两 个 引 用 。 创 建 了 两 个 对 象 。 两 个 引 用 分 别 指 向 不 同 的 两 个 对 象 。Java代 码1. String str1 = “abc“;2. String str2 = new String(“abc“);3. System.out.println(str1=str2); /false创 建 了 两 个 引 用 。 创 建 了 两 个 对 象 。 两 个 引 用 分 别 指 向 不 同 的 两 个 对 象 。接 下 来 我 们 再 来 看 看 intern(
35、)方 法 , 它 的 定 义 如 下 :Java代 码1. public native String intern();这 是 一 个 本 地 方 法 。 在 调 用 这 个 方 法 时 , JAVA虚 拟 机 首 先 检 查 String Pool 中是 否 已 经 存 在 与 该 对 象 值 相 等 对 象 存 在 , 如 果 有 则 返 回 字 符 串 池 中 对 象 的 引 用 ;如 果 没 有 , 则 先 在 String Pool 中 创 建 一 个 相 同 值 的 String 对 象 , 然 后 再 将 它的 引 用 返 回 。例 程 6:Java代 码1. public cl
36、ass TestString2. public static void main(String args)3.4. String s1 = new String(“abc“);/语 句 15. String s2 = “abc“;/语 句 26. String s3 = new String(“abc“);/语 句 37.8. System.out.println(s1 = s2);/语 句 49. System.out.println(s1 = s3);/语 句 510. System.out.println(s2 = s3);/语 句 611.12. System.out.println(
37、s1 = s1.intern();/语 句713. System.out.println(s2 = s2.intern();/语 句814. System.out.println(s1.intern() = s2.intern();/语 句 915.16. String hello = “hello“;/语 句 1017. String hel = “hel“;/语 句 1118. String lo = “lo“;/语 句 1219.20. System.out.println(hello = “hello“);/语 句1321. System.out.println(hello = “he
38、l“ + “lo“);/语 句 1422. System.out.println(hello = “hel“ + lo);/语 句 1523. System.out.println(hello = hel + lo);/语句 1624. 25.问 题 1: 当 执 行 完 语 句 (1)时 , 在 内 存 里 面 生 成 几 个 对 象 ?它 们 是 什 么 ?在 什 么 地方 ?当 执 行 完 语 句 (1)时 , 在 内 存 里 面 创 建 了 两 个 对 象 , 它 们 的 内 容 分 别 都 是 abc,分 别 在 StringPool(常 量 池 )和 Heap(堆 )里 。 其 字
39、 符 串 的 创 建 过 程 如 下 : 首 先 在String Pool里 面 查 找 查 找 是 否 有 “abc“, 如 果 有 就 直 接 使 用 , 但 这 是 本 程 序 的第 一 条 语 句 , 故 不 存 在 一 个 对 象 “abc“, 所 以 要 在 String Pool中 生 成 一 个 对 象“abc“, 接 下 来 , 执 行 newString(“abc“)构 造 方 法 , new出 来 的 对 象 都 放 在 Heap里 面 。 在 Heap里 又 创 建 了 一 个 “abc“的 对 象 。 这 时 内 存 里 就 有 两 个 对 象 了 , 一 个在 St
40、ring Pool 里 面 , 一 个 在 Heap里 面 。问 题 2: 当 执 行 完 语 句 (2)时 , 在 内 存 里 面 一 共 有 几 个 对 象 ?它 们 是 什 么 ?在 什 么地 方 ?当 执 行 完 语 句 (2)时 , 在 内 存 里 面 一 个 对 象 也 没 有 创 建 。 当 我 们 定 义 语 句 (2)的 时候 , 如 果 我 们 用 字 符 串 的 常 量 值 (字 面 值 )给 s2赋 值 的 话 , 那 么 首 先 JVM还 是 从String Pool里 面 去 查 找 有 没 有 内 容 为 abc的 这 样 一 个 对 象 存 在 , 我 们 发
41、现 当 我们 执 行 完 语 句 (1)的 时 候 , StringPool里 面 已 经 存 在 了 内 容 为 abc的 对 象 , 那 么就 不 会 再 在 StringPool里 面 去 生 成 内 容 为 abc的 字 符 串 对 象 了 。 而 是 会 使 用 已经 存 在 String Pool里 面 的 内 容 为 abc的 字 符 串 对 象 , 并 且 会 将 s2这 个 引 用 指向 String Pool里 面 的 内 容 为 abc的 字 符 串 对 象 , s2存 放 的 是 String Pool里面 的 内 容 为 abc的 字 符 串 对 像 的 地 址 。
42、也 就 是 说 当 你 使 用 String s2 = “abc“,即 使 用 字 符 串 常 量 (“abc“)给 定 义 的 引 用 (str2)赋 值 的 话 , 那 么 它 首 先 是 在String Pool里 面 去 找 有 没 有 内 容 为 abc的 字 符 串 对 象 存 在 , 如 果 有 的 话 , 就 不用 创 建 新 的 对 象 , 直 接 引 用 String Pool里 面 已 经 存 在 的 对 象 ; 如 果 没 有 的 话 ,就 在 String Pool里 面 去 创 建 一 个 新 的 对 象 , 接 着 将 引 用 指 向 这 个 新 创 建 的 对象
43、 。 所 以 , 当 执 行 完 语 句 (2)时 内 存 里 面 一 共 有 2个 对 象 , 它 们 的 内 容 分 别 都 是abc, 在 String Pool里 面 一 个 内 容 abc的 对 象 , 在 Heap里 面 有 一 个 内 容 为 abc的 对 象 。问 题 3: 当 执 行 完 语 句 (3)时 , 在 内 存 里 面 一 共 有 几 个 对 象 ?它 们 是 什 么 ?在 什 么地 方 ?当 执 行 完 语 句 (3)时 , 其 执 行 过 程 是 这 样 的 : 它 首 先 在 String Pool里 面 去 查 找有 没 有 内 容 为 abc的 字 符 串
44、 对 象 存 在 , 发 现 有 这 个 对 象 存 在 , 它 就 不 去 创 建 一个 新 的 对 象 。 接 着 执 行 new., 只 要 在 java里 面 有 关 键 字 new存 在 , 不 管 内 容是 否 相 同 , 都 表 示 它 将 生 成 一 个 新 的 对 象 , new多 少 次 , 就 生 成 多 少 个 对 象 , 而且 新 生 成 的 对 象 都 是 在 Heap里 面 , 所 以 它 会 在 Heap里 面 生 成 一 个 内 容 为 abc的 对 象 , 并 且 将 它 的 地 址 赋 给 了 引 用 s3, s3就 指 向 刚 在 Heap里 面 生 成
45、 的 内 容 为abc的 对 象 。 所 以 , 当 执 行 完 语 句 (3)时 , 内 存 里 面 一 共 有 3个 对 象 , 其 中 包 含了 在 String Pool里 面 一 个 内 容 为 abc的 字 符 串 对 象 和 在 Heap里 面 包 含 了 两 个内 容 为 abc的 字 符 串 对 象 。问 题 4: 当 执 行 完 语 句 (4)(5)(6)后 , 它 们 的 结 果 分 别 是 什 么 ?在 java里 面 , 对 象 用 “=“永 远 比 较 的 是 两 个 对 象 的 内 存 地 址 , 换 句 话 说 , 是 比较 “=“左 右 两 边 的 两 个 引
46、 用 是 否 指 向 同 一 个 对 象 。 对 于 java里 面 的 8种 原 生 数据 类 型 来 说 , “=“比 较 的 是 它 们 的 字 面 值 是 不 是 一 样 的 ; 对 应 用 类 型 来 说 , 比 较的 是 它 们 的 内 存 地 址 是 不 是 一 样 的 。 在 语 句 (1)(2)(3)中 , 由 于 s1、 s2、 s3指 向不 同 的 对 象 , 它 们 的 内 存 地 址 就 不 一 样 , 因 此 可 以 说 当 执 行 完 语 句 (4)(5)(6),它 们 返 回 的 结 果 都 是 false。问 题 5: 当 执 行 完 语 句 (7)(8)(9
47、)后 , 它 们 的 结 果 分 别 是 什 么 ?首 先 , s1这 个 对 象 指 向 的 是 堆 中 第 一 次 new.生 成 的 对 象 , 当 调 用 intern 方法 时 , 如 果 String Pool已 经 包 含 一 个 等 于 此 String 对 象 的 字 符 串 (该 对 象 由equals(Object)方 法 确 定 ) , 则 返 回 指 向 String Pool中 的 字 符 串 对 象 的 引 用 。因 为 String Pool中 有 内 容 为 abc的 对 象 , 所 以 s1.intern()返 回 的 是 StringPool中 的 内 容
48、 为 abc的 字 符 串 对 象 的 内 存 地 址 , 而 s1却 是 指 向 Heap上 内 容 为abc的 字 符 串 对 象 的 引 用 。 因 而 , 两 个 引 用 指 向 的 对 象 不 同 , 所 以 , s1 =s1.intern() 为 false, 即 语 句 (7)结 果 为 false。对 于 s2.intern(), 它 还 是 会 首 先 检 查 StringPool中 是 否 有 内 容 为 abc的 对 象 ,发 现 有 , 则 将 String Pool中 内 容 为 abc的 对 象 的 地 址 赋 给 s2.intern()方 法 的返 回 值 。 因
49、 为 s2和 s2.intern()方 法 的 返 回 值 指 向 的 是 同 一 个 对 象 , 所 以 , s2=s2.intern()的 结 果 为 true,, 即 语 句 (8)结 果 为 true。对 于 s1.intern(), 它 首 先 检 查 String Pool中 是 否 有 内 容 为 abc的 对 象 , 发 现有 , 则 将 String Pool中 内 容 为 abc的 对 象 的 赋 给 s1.intern()方 法 的 返 回 值 。对 于 s2.intern(),首 先 检 查 String Pool中 是 否 有 内 容 为 abc的 对 象 , 发 现 有 ,则 将 String Pool中 内 容 为 abc的 对 象 的 地 址 赋 给 s2.intern()方 法 的 返 回 值 。因 为 两 者 返 回 的 地 址 都 指 向 同