java练习题含答案.pdf_第1页
java练习题含答案.pdf_第2页
java练习题含答案.pdf_第3页
java练习题含答案.pdf_第4页
java练习题含答案.pdf_第5页
已阅读5页,还剩15页未读 继续免费阅读

付费下载

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1.编写程序,用数组实现乘法小九九的存储和输出。 【提示:采用多个一维数组。 】 public class Multipation public static void main(String args) / TODO Auto-generated method stub int x=new int99; for(int i=0;i9;i+) for(int j=0;j=j) int m=i+1; int n=j+1; xij=m*n; System.out.print(m+“*“+n+“=“+xij); System.out.println(); 2. 定义一个类 Student,属性为学号、姓名和成绩;方法为增加记录 SetRecord 和得到记录 GetRecord。SetRecord 给出学号、姓名和成绩的赋值,GetRecord 通过学号得到考生的成绩。 public class Student /* * param args */ private int ID; private String name; private float score; public void SetRecord(int ID,String name,float score) this.ID=ID; =name; this.score=score; public float getRecord(int ID) if(ID=this.ID) return this.score; else return -1; public static void main(String args) / TODO Auto-generated method stub Student s=new Student(); s.SetRecord(0,“alex“,100); float Sco=s.getRecord(0); System.out.print(Sco); 3.给出上题中设计类的构造函数,要求初始化一条记录(学号、姓名、成绩)。 4. public class Student 5. 6./* 7.* param args 8.*/ 9.private int ID; 10.private String name; 11.private float score; 12. 13.Student(int ID,String name,float score) 14.this.ID=0; 15.=“666“; 16.this.score=65; 17. 18.public void SetRecord(int ID,String name,float score) 19.this.ID=ID; 20.=name; 21.this.score=score; 22. 23.public float getRecord(int ID) 24.if(ID=this.ID) 25.return this.score; 26.else 27.return -1; 28. 29. 30.public static void main(String args) 31./ TODO Auto-generated method stub 32.Student s=new Student(0,“sdfs“,12); 33./s.SetRecord(0,“alex“,100); 34.float Sco=s.getRecord(0); 35.System.out.print(Sco); 36. 37. 4.编写程序,测试字符串“你好,欢迎来到 Java 世界”的长度,将字符串的长度转换成字符 串进行输出, 并对其中的“Java”四个字母进行截取, 输出截取字母以及它在字符串中的位置。 public class StringTest /* * param args */ public static void main(String args) / TODO Auto-generated method stub String str=“你好,欢迎来到Java世界“; int length=str.length(); char stringArr = str.toCharArray(); /System.out.print(stringArr); for(int i=0;ilength;i+) /System.out.print(stringArri); /System.out.print(stringArr0); if(J=stringArri) System.out.print(i); 1. 自己设计一个坐标类,能提供以下方法如求当前坐标和其他坐标之间的距离等方 法,要求所有变量为私有变量,并提供两个构造函数。 public class XYdistance private int x; private int y; XYdistance() setX(0); setY(0); public void setX(int x) this.x = x; public int getX() return x; public void setY(int y) this.y = y; public int getY() return y; public static void main(String args) / TODO Auto-generated method stub XYdistance m_1= new XYdistance(); m_1.setX(10); m_1.setY(10); XYdistance m_2= new XYdistance(); double distance=(m_1.getX()-m_2.getX()*(m_1.getX()-m_2.getX()+(m_1.getY()- m_2.getY()*(m_1.getY()-m_2.getY(); double result=Math.sqrt(distance); System.out.println(result); 编写使用静态变量统计一个类产生的实例对象的个数的程序? public class Static private static int number; public Static() /number=number+1; +number; /System.out.println(+number); public static void main(String args) / TODO Auto-generated method stub new Static(); /m_1.Static(); System.out.println(Static.number); 创建 string 对象过程的内存分配: 常量池常量池(ConstantConstant PoolPool):指的是在编译期被确定,并被保存在已编译的.class 文件中的一些数据。JVM 虚拟机为每个被装载的类型维护一个常量池。常量池就 是该类型所用到常量的一个有序集和,包括直接常量(String,Integer 和 Floating point 常量)和对其他类型,字段和方法的符号引用。对于 String 常 量, 它的值是在常量池中的。 而 JVM 中的常量池在内存当中是以表的形式存在的, 对于 String 类型, 有一张固定长度的 CONSTANT_String_info 表用来存储文字字 符串值,注意:该表只存储文字字符串值,不存储符号引用。 1 1、StringString s s = = “abc“;“abc“; 创建过程分析创建过程分析: 在 class 文件被 JVM 装载到内存中, JVM 会创建一块 String Pool (String 缓冲池)。当执行 String s = “abc”;时,JVM 首先在 String Pool 中查看是否存在字符串对象“abc”(如何查看呢?用 equals()方法判断),如 果已存在该对象,则不用创建新的字符串对象“abc”,而直接使用 String Pool 中已存在的对象“abc”,然后将引用 s 指向该对象;如果不存在该对象,则先 在 String Pool 中创建一个新的字符串对象“abc”,然后将引用 s 指向 String Pool 中创建的新对象。 注意:使用注意:使用“字符串常量字符串常量”引号创建的字符串对象时,在编译期就已经确定将引号创建的字符串对象时,在编译期就已经确定将 该对象存储到该对象存储到 StringString PoolPool 中了。因此,中了。因此,StringString s s = = “abcabc”只会在编译期,只会在编译期, 在在 StringString PoolPool 中创建一个对象。中创建一个对象。 例如: Java 代码 1. Strings1=“abc“; 2. Strings2=“abc“; 3. System.out.println(s1=s2);/true 结果说明结果说明:JVM 创建了两个引用 str1 和 str2,但在 String Pool 中只创建了一 个对象,而且两个引用都指向了同一个对象。 2 2、StringString s s = = newnew String(“abc“);String(“abc“); 创建过程分析创建过程分析:当执行 String s = new String(“abc”);时,JVM 首先在 String Pool 中查看是否存在字符串对象“abc”,如果不存在该对象,则先在 String Pool 中创建一个新的字符串对象“abc”,然后执行 new String(“abc”)构造 方法, 在Heap里又创建一个新的字符串对象“abc” (new出来的对象都放在Heap 里面),并将引用 s 指向 Heap 中创建的新对象;如果已存在该对象,则不用创 建新的字符串对象“abc”,而直接使用 String Pool 中已存在的对象“abc”, 然后执行 new String(“abc”)构造方法,在 Heap 里又创建一个新的字符串对 象“abc”,并将引用 s 指向 Heap 中创建的新对象。 注意:使用注意:使用 newnew StringString(“”“”)创建的字符串对象时,会在运行期创建新对象)创建的字符串对象时,会在运行期创建新对象 存储到存储到 HeapHeap 中。因此,中。因此,newnew StringString(“abcabc”)创建字符串对象时,会创建)创建字符串对象时,会创建 2 2 个对象,编译期在个对象,编译期在 StringString PoolPool 中创建一个,运行时中创建一个,运行时 HeapHeap 中创建一个。中创建一个。 这里使用了 Java 代码 1. publicString(Stringoriginal) 这个构造方法,作用作用:初始化一个新创建的初始化一个新创建的 StringString 对象对象,使其表示一个与参数使其表示一个与参数 相同的字符序列;换句话说,新创建的字符串是该参数字符串的副本。相同的字符序列;换句话说,新创建的字符串是该参数字符串的副本。 由于 Sring 类是不可变的,因而不必使用该构造方法,除非需要 original 的显 式副本。 例如: Java 代码 1. Strings1=newString(“abc“); 2. Strings2=newString(“abc“); 3. System.out.println(s1=s2);/false 结果说明结果说明:只要是用 new()来新建对象的,都会在堆(Heap)中创建,而且其字 符串是单独存值的,即使与 String Pool 中的数据相同,也不会与 String Pool 中的数据共享。 例程 1: Java 代码 1. Strings1=“abcdef“; 2. Strings2=“abcdef“; 3. Strings3=“abc“+“def“;/编译期自动优化为 Strings3=“abcdef“; 4. System.out.println(s1=s2); 5. System.out.println(s1=s3); 6. System.out.println(s2=s3); 运行结果: true true true 结果说明结果说明:字符串常量生成的字符串对象在 String Pool 中只有一个拷贝,且它 是在编译期就被确定了,所以“s1 = s2”;“abc”和“def”都是字符串常量, 当一个字符串由多个字符串常量连接而成时,它自己也肯定是字符串常量(它在 编译期就被解析为一个字符串对象了, 即 class 文件中就已经存在“abcdef”) , 所以在字符串生成字符串对象时,s3 也是 String Pool 中“abcdef”的一个引 用。故 JVM 对于字符串常量的“+“号连接,在程序编译期,JVM 就将常量字符串 的“+“连接优化为连接后的值。 例程 2: Java 代码 1. Strings1=“abc“; 2. Strings2=“def“; 3. Strings3=“abcdef“; 4. Strings4=“abc“+“def“; 5. Strings5=s1+“def“; 6. Strings6=“abc“+s2; 7. Strings7=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); 运行结果如下: true false false false 结果说明结果说明:JVM 对于有字符串引用存在的字符串“+“连接中,而引用的值在程序 编译期是无法确定的,即 s1 + “def”无法被编译器优化,只有在程序运行期 来动态分配并将连接后的新地址赋给 s5。 例程 3: Java 代码 1. finalStrings1=“abc“; 2. Strings2=“def“; 3. Strings3=“abcdef“; 4. Strings4=“abc“+“def“; 5. Strings5=s1+“def“; 6. Strings6=“abc“+s2; 7. Strings7=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); 运行结果如下: true true false false 例程 4: Java 代码 1. finalStrings1=“abc“; 2. finalStrings2=“def“; 3. Strings3=“abcdef“; 4. Strings4=“abc“+“def“; 5. Strings5=s1+“def“; 6. Strings6=“abc“+s2; 7. Strings7=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); 运行结果如下: true true true true 结果说明结果说明: 例程 3 和例程 4 与例程 2 的区别是, 例程 3 在字符串 s1 前加了 final 修饰,例程 4 在字符串 s1 和 s2 前都加了 final 修饰。对于 final 修饰的变量, 它在编译时被解析为常量值的一个本地拷贝存储到自己的常量池中或嵌入到它 的字节码流中。所以此时的 s1 + “def”和“abc“ + “def“效果是一样的。接着 后面两个含引用的字符串连接,JVM 会进行相同的处理。故上面程序后面三个的 结果为 true。 例程 5: Java 代码 1. publicstaticvoidmain(Stringargs) 2.Strings1=“abc“; 3.finalStrings2=getDef(); 4.Strings3=“abcdef“; 5.Strings4=“abc“+s2; 6.Strings5=s1+s2; 7.System.out.println(s3=s4); 8.System.out.println(s3=s5); 9. Java 代码 1. privatestaticStringgetDef() 2.return“def“; 3. 程序运行结果如下: false false 结果说明结果说明:JVM 对于方法调用给字符串引用赋值的情况,引用指向字符串的值在 编译期是无法确定的,只有在程序运行调用方法后,将方法的返回值“def”和 “abc”动态连接并分配新地址赋值给 s4,所以上述程序的结果都为 false。 通过以上的例子可知: Java 代码 1. Strings=“a“+“b“+“c“; 等价于: Java 代码 1. Strings=“abc“; 编译期,直接优化,进行常量连接。 对于: Java 代码 1. Stringa=“a“; 2. Stringb=“b“; 3. Stringc=“c“; 4. Strings=a+b+c; 就不等价于:等价于: Java 代码 1. Strings=“abc“; 最终结果等于: Java 代码 1. StringBuilderbuilder=newStringBuilder(); 2. builder.append(a); 3. builder.append(b); 4. builder.append(c); 5. Strings=builder.toString(); 去看 StringBuilder 的 toString()方法: Java 代码 1. publicStringtoString() 2. /Createacopy,dontsharethearray 3. returnnewString(value,0,count); 4. 可以发现是通过 new String()返回了一个 String 对象,也就是说在堆中创建 了对象。这时候会不会在池中出现“abc“这个对象呢?(question 还没解决) 生成 String s 的过程中,编译器使用 sb 执行的过程:创建一个 StringBuffer 对象,使用 append()向此 StringBuffer 对象直接添加新的字符串(而不是每次 制作一个新的副本)。 对于对于 StringString c c = = “c“;String“c“;String s s = = “a“a“ + + “b“b“ + + c;c;,编译器将会先将,编译器将会先将“a“a“ + + “b“b“ 作为编译时常量作为编译时常量,优化生成成字面常量优化生成成字面常量“ab“ab“ ,然后生成一个然后生成一个 StringBuilderStringBuilder 对对 象,接着调用两次象,接着调用两次 append()append()方法,即方法,即: : StringString s s = = newnew Builder().append(“ab“).append(c)Builder().append(“ab“).append(c) .toString();.toString(); 对于对于 StringString a a = = “a“;String“a“;String s s = = a a + + “b“b“ + + “c“;“c“;,编译器分析,编译器分析 a a 为引用变量为引用变量, 后面的后面的“b“b“ + + “c“c“就不会作为编译时常量来运算了。相当于执行:就不会作为编译时常量来运算了。相当于执行: StringString s s = = newnew Builder().append(a).append(“b“)Builder().append(a).append(“b“) .append(“c“).append(“c“) .toString();.toString(); 对于对于 StringString b b = = “b“;String“b“;String s s = = “a“a“ + + b b + + “c“;“c“;,这种形式的就没办法优化,这种形式的就没办法优化 了,直接生成了,直接生成 StringBuilderStringBuilder 对象,然后调用三次对象,然后调用三次 append()append()方法,即:方法,即: StringString s s = = newnew Builder().append(“a“).append(b)Builder().append(“a“).append(b) .append(“c“).append(“c“) .toString();.toString(); 接着,我们再看以下代码: Java 代码 1. Stringstr1=“abc“;/是字符串常量,它在编译期被确定,放在常 量池中(共享内容值) 2. /newString()创建的字符串不放入常量池中 3. Stringstr2=newString(“abc“);/不是字符串常量, 不在编译期确 定(不共享内容值) Java 代码 1. Stringstr1=newString(“abc“); 2. Stringstr2=“abc“; 3. System.out.println(str1=str2);/false 创建了两个引用。创建了两个对象。两个引用分别指向不同的两个对象。创建了两个引用。创建了两个对象。两个引用分别指向不同的两个对象。 Java 代码 1. Stringstr1=“abc“; 2. Stringstr2=newString(“abc“); 3. System.out.println(str1=str2);/false 创建了两个引用。创建了两个对象。两个引用分别指向不同的两个对象。创建了两个引用。创建了两个对象。两个引用分别指向不同的两个对象。 接下来我们再来看看 intern()方法,它的定义如下: Java 代码 1. publicnativeStringintern(); 这是一个本地方法。在调用这个方法时,这是一个本地方法。在调用这个方法时,JAVAJAVA 虚拟机首先检查虚拟机首先检查 StringString PoolPool 中中 是否已经存在与该对象值相等对象存在是否已经存在与该对象值相等对象存在,如果有则返回字符串池中对象的引用如果有则返回字符串池中对象的引用; 如果没有,则先在如果没有,则先在 StringString PoolPool 中创建一个相同值的中创建一个相同值的 StringString 对象,然后再将它对象,然后再将它 的引用返回。的引用返回。 例程 6: Java 代码 1. publicclassTestString 2.publicstaticvoidmain(Stringargs) 3. 4.Strings1=newString(“abc“);/语句 1 5.Strings2=“abc“;/语句 2 6.Strings3=newString(“abc“);/语句 3 7. 8.System.out.println(s1=s2);/语句 4 9.System.out.println(s1=s3);/语句 5 10.System.out.println(s2=s3);/语句 6 11. 12.System.out.println(s1=ern();/语句 7 13.System.out.println(s2=ern();/语句 8 14.System.out.println(ern()=ern() ;/语句 9 15. 16.Stringhello=“hello“;/语句 10 17.Stringhel=“hel“;/语句 11 18.Stringlo=“lo“;/语句 12 19. 20.System.out.println(hello=“hello“);/语句 13 21.System.out.println(hello=“hel“+“lo“);/ /语句 14 22.System.out.println(hello=“hel“+lo);/ 语句 15 23.System.out.println(hello=hel+lo);/语 句 16 24. 25. 问题问题 1 1:当执行完语句:当执行完语句(1)(1)时,在内存里面生成几个对象时,在内存里面生成几个对象? ?它们是什么它们是什么? ?在什么地在什么地 方方? ? 当执行完语句(1)时,在内存里面创建了两个对象,它们的内容分别都是 abc, 分别在 String Pool(常量池)和 Heap(堆)里。其字符串的创建过程如下:首先在 String Pool 里面查找查找是否有 “abc“,如果有就直接使用,但这是本程序的 第一条语句,故不存在一个对象“abc“,所以要在 String Pool 中生成一个对象 “abc“,接下来,执行 new String(“abc“)构造方法,new 出来的对象都放在 Heap 里面。在 Heap 里又创建了一个“abc“的对象。这时内存里就有两个对象了,一个 在 String Pool 里面,一个在 Heap 里面。 问题问题 2 2:当执行完语句:当执行完语句(2)(2)时,在内存里面一共有几个对象时,在内存里面一共有几个对象? ?它们是什么它们是什么? ?在什么在什么 地方地方? ? 当执行完语句(2)时,在内存里面一个对象也没有创建。当我们定义语句(2)的时 候,如果我们用字符串的常量值(字面值)给 s2 赋值的话,那么首先 JVM 还是从 String Pool 里面去查找有没有内容为 abc 的这样一个对象存在,我们发现当我 们执行完语句(1)的时候,StringPool 里面已经存在了内容为 abc 的对象,那么 就不会再在 String Pool 里面去生成内容为 abc 的字符串对象了。而是会使用已 经存在 String Pool 里面的内容为 abc 的字符串对象,并且会将 s2 这个引用指 向 String Pool 里面的内容为 abc 的字符串对象,s2 存放的是 String Pool 里 面的内容为 abc 的字符串对像的地址。也就是说当你使用 String s2 = “abc“, 即使用字符串常量(“abc“)给定义的引用(str2)赋值的话,那么它首先是在 String Pool 里面去找有没有内容为 abc 的字符串对象存在,如果有的话,就不 用创建新的对象,直接引用 String Pool 里面已经存在的对象;如果没有的话, 就在 String Pool 里面去创建一个新的对象,接着将引用指向这个新创建的对 象。所以,当执行完语句(2)时内存里面一共有 2 个对象,它们的内容分别都是 abc,在 String Pool 里面一个内容 abc 的对象,在 Heap 里面有一个内容为 abc 的对象。 问题问题 3 3:当执行完语句:当执行完语句(3)(3)时,在内存里面一共有几个对象时,在内存里面一共有几个对象? ?它们是什么它们是什么? ?在什么在什么 地方地方? ? 当执行完语句(3)时,其执行过程是这样的:它首先在 String Pool 里面去查找 有没有内容为 abc 的字符串对象存在,发现有这个对象存在,它就不去创建 一 个新的对象。接着执行 new.,只要在 java 里面有关键字 new 存在,不管内容 是否相同,都表示它将生成一个新的对象,new 多少次,就生成多少个对象,而 且新生成的对象都是在 Heap 里面,所以它会在 Heap 里面生成一个内容为 abc 的对象,并且将它的地址赋给了引用 s3,s3 就指向刚在 Heap 里面生成的内容为 abc 的对象。所以,当执行完语句(3)时,内存里面一共有 3 个对象,其中包含 了在 String Pool 里面一个内容为 abc 的字符串对象和在 Heap 里面包含了两个 内容为 abc 的字符串对象。 问题问题 4 4:当执行完语句:当执行完语句(4)(5)(6)(4)(5)(6)后,它们的结果分别是什么后,它们的结果分别是什么? ? 在 java 里面,对象用“=“永远比较的是两个对象的内存地址,换句话说,是比 较“=“左右两边的两个引用是否指向同一个对象。对于 java 里面的 8 种原生数 据类型来说,“=“比较的是它们的字面值是不是一样的;对应用类型来说,比较 的是它们的内存地址是不是一样的。在语句(1)(2)(3)中,由于 s1、s2、s3 指向 不同的对象,它们的内存地址就不一样,因此可以说当执行完语句(4)(5)(6), 它们返回的结果都是 false。 问题问题 5 5:当执行完语句:当执行完语句(7)(8)(9)(7)(8)(9)后,它们的结果分别是什么后,它们的结果分别是什么? ? 首先,s1 这个对象指向的是堆中第一次 new.生成的对象,当调用 intern 方 法时,如果 String Pool 已经包含一个等于此 String 对象的字符串(该对象由 equals(Object)方法确定),则返回指向 String Pool 中的字符串对象的引用。 因为 String Pool 中有内容为 abc 的对象,所以 ern()返回的是 String Pool 中的内容为 abc 的字符串对象的内存地址,而 s1 却是指向 Heap 上内容为 abc 的字符串对象的引用。因而,两个引用指向的对象不同,所以,s1 = ern() 为 false,即语句(7)结果为 false。 对于 ern(), 它还是会首先检查 String Pool 中是否有内容为 abc 的对象, 发现有,则将 String Pool 中内容为 abc 的对象的地址赋给 ern()方法的 返回值。 因为 s2 和 ern()方法的返回值指向的是同一个对象, 所以, s2 = ern()的结果为 true,,即语句(8)结果为 true。 对于 ern(),它首先检查 String Pool 中是否有内容为 abc 的对象,发现 有,则将 String Pool 中内容为 abc 的对象的赋给 ern()方法的返回值。 对于 ern(),首先检查 String Pool 中是否有内容为 abc 的对象,发现有, 则将 String Pool 中内容为 abc 的对象的地址赋给 ern()方法的返回值。 因为两者返回的地址都指向同一个对象,所以,ern() = ern() 的结果为 true,,即是语句(9)结果为 true。 因此,当执行完语句(7)(8)(9)后,它们的结果分别是 false、true、true。 问题问题 6 6:当执行完语句:当执行完语句(13)(14)(13)(14) (15)(16)(15)(16)后,它们的结果分别是什么后,它们的结果分别是什么? ? hello = “hello“引用 hello 指向的对象就是 String Pool 中的“hello”,即 语句(13)的结果为 true。 hello = “hel“ + “lo“当加号两边都是常量值时,就会组成一个新的常量值 “hello“在 String Pool 里面,如果 String Pool 已经有相同内容的就不会再创 建,则直接返回 String Pool 里面的内容为“hello“的字符串对象的内存地址, 所以,hello = “hel“ + “lo“结果为 true。 hello =“hel“ + lo 当加号两边有一个不是常量值,会在堆里面创建一个新的 “hello“对象,一个在 String Pool 中,一个在 Heap 中,故输出 false 。 hel + lo 同上,输出 false。 因此, 当执行完语句(7)(8)(9)后, 它们的结果分别是 true、 true、 false、 false。 例程 7: Java 代码 1. Strings1=“abc“; 2. Strings2=newString(“abc“); 3. Strings3=newString(“abc“); 4. ern();/虽然执行了 ern(),但它的返回值没有赋给 s2 5. s3=ern();/把 StringPool 中“abc”的引用赋给 s3 6. System.out.println(s1=s2); 7. System.out.println(s1=ern(); 8. System.out.println(s1=s3); 运行结果如下: false true true 结果说明结果说明:因为 ern()只是执行了,而没有把 String Pool 中的“abc” 的地址赋给 s2,所以 s1 还是指向 String Pool 中的“abc”,s2 则指向 Heap 中的“abc”,对于 s1 = s2,返回值为 false;对于 s1 = ern(),其 中 ern()的返回值为指向 String Pool 中“abc”的地址,故 ern() 与 s1 指向同一个对象,因而返回 true;因为 s3 = ern()把 String Pool 中的“abc”的地址赋给了 s3, 此时 s1 和 s3 指向的是同一对象, 即 String Pool 中的“abc“,因而返回 true。 例程 8: Java 代码 1. Strings1=“abc“; 2. Strings2=newString(“abc“); 3. Strings3=“a“+newString(“bc“); 4. System.out.println(s1=s2); 5. System.out.println(s1=s3); 6. System.out.println(s2=s3); 运行结果如下: false false false 结果说明结果说明: s1 指向 String Pool 中的字符串对象“abc”,编译期确定; s2 指向 Heap 中的字符串对象“abc”,运行期确定; s3 指向 Heap 中的另一个字符串对象“abc”,运行期确定。 注意:String s3 = “a“ + new String(“bc“);等价于 String s3 = new StringBuilder().append(“a“).append(new String(“bc“).toString(); 思考思考:String s = “a“ + new String(“b“) + “c“;产生了那几个对象? 解:等价于 String s = new StringBuilder().append(“a“).append(new String(“b“).append(“c“).toString(),会在 String Pool 中产生“a“、“b“、 “c“三个对象,在 Heap 中产生“b“、“abc“两个个对象。一共 5 个字符串对象。 例程 9: Java 代码 1. Strings1=“Hello“; 2. s1=“Java“; 3. Strings2=“Hello“; 4. Strings3=newString(“Hello“); 5. System.out.println(s1=s2); 6. System.out.println(s2=s3); 运行结果如下: false false 分析这段程序的执行过程分析这段程序的执行过程: 首先在加载 Java 程序时,JVM 会创建一片的内存空间(String Pool)专门存入 string 对象。 String s1 = “Hello“,现在栈中创建一个字符串引用 s1,然后 JVM 会在 String Pool 中查找是否存在“Hello“,如果存在,则直接使用它,将其地址赋给 s1,如 果不存在(这时 String Pool 中显然不存在“Hello“),则在 String Pool 中创 建“Hello“,并将其地址赋给 s1。 s1 = “Java“,JVM 会在 String Pool 中查找是否存在“Java“,如果存在,则直 接使用它,将其地址赋给 s1,如果不存在(这时 String Pool 中显然不存在 “Java“),则在 String Pool 中创建“Java“,并将其地址赋给 s1。而原来的字而原来的字 符串对象符串对象“Hello“Hello“仍然在仍然在 StringString PoolPool 中,没有消失,因为中,没有消失,因为 StringString 对象的值是对象的值是 不能被修改的。这里只是改变了引用的值即引用指向的对象的地址,而没有改不能被修改的。这里只是改变了引用的值即引用指向的对象的地址,而没有改 变它所引用的对象。变它所引用的对象。 String s2 = “Hello“,JVM 会在 String Pool 里查看有没有字符串“Hello“,若 有,则返回它的地址给 s2,否则,创建新的 String 对象“Hello“, 放到 String Pool 里。这里由于“Hello“对象已经创建,并存在于 String Pool 中,因而不需 要重新创建 St

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论