《java练习题(共15页).doc》由会员分享,可在线阅读,更多相关《java练习题(共15页).doc(16页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、精选优质文档-倾情为你奉上1. 编写程序,用数组实现乘法小九九的存储和输出。【提示:采用多个一维数组。】 public class Multipation public static void main(String args) / TODO Auto-generated method stubint 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,属性为学号、
2、姓名和成绩;方法为增加记录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;this.name=name;this.score=score;public float getRecord(int ID
3、)if(ID=this.ID)return this.score;elsereturn -1;public static void main(String args) / TODO Auto-generated method stubStudent s=new Student();s.SetRecord(0,alex,100);float Sco=s.getRecord(0);System.out.print(Sco);3. 给出上题中设计类的构造函数,要求初始化一条记录(学号、姓名、成绩)。4. public class Student 5. /*6. * param args7. */8.
4、 private int ID;9. private String name;10. private float score;11. Student(int ID,String name,float score)12. this.ID=0;13. this.name=666;14. this.score=65;15. 16. public void SetRecord(int ID,String name,float score)17. this.ID=ID;18. this.name=name;19. this.score=score;20. 21. public float getReco
5、rd(int ID)22. if(ID=this.ID)23. return this.score;24. else25. return -1;26. 27. public static void main(String args) 28. / TODO Auto-generated method stub29. Student s=new Student(0,sdfs,12);30. /s.SetRecord(0,alex,100);31. float Sco=s.getRecord(0);32. System.out.print(Sco);33. 34. 4. 编写程序,测试字符串“你好,
6、欢迎来到Java世界”的长度,将字符串的长度转换成字符串进行输出,并对其中的“Java”四个字母进行截取,输出截取字母以及它在字符串中的位置。public class StringTest /* * param args */public static void main(String args) / TODO Auto-generated method stubString str=你好,欢迎来到Java世界;int length=str.length();char stringArr = str.toCharArray(); /System.out.print(stringArr);for
7、(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
8、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 stubXYdistance 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.g
9、etX()+(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
10、Auto-generated method stubnew Static();/m_1.Static();System.out.println(Static.number);创建string对象过程的内存分配:常量池(Constant Pool):指的是在编译期被确定,并被保存在已编译的.class文件中的一些数据。JVM虚拟机为每个被装载的类型维护一个常量池。常量池就是该类型所用到常量的一个有序集和,包括直接常量(String,Integer和 Floating point常量)和对其他类型,字段和方法的符号引用。对于String常量,它的值是在常量池中的。而JVM中的常量池在内存当中是以表
11、的形式存在的, 对于String类型,有一张固定长度的CONSTANT_String_info表用来存储文字字符串值,注意:该表只存储文字字符串值,不存储符号引用。 1、String s = abc; 创建过程分析:在class文件被JVM装载到内存中,JVM会创建一块String Pool(String缓冲池)。当执行String s = “abc”;时,JVM首先在String Pool中查看是否存在字符串对象“abc”(如何查看呢?用equals()方法判断),如果已存在该对象,则不用创建新的字符串对象“abc”,而直接使用String Pool中已存在的对象“abc”,然后将引用s指向
12、该对象;如果不存在该对象,则先在String Pool中创建一个新的字符串对象“abc”,然后将引用s指向String Pool中创建的新对象。 注意:使用“字符串常量”引号创建的字符串对象时,在编译期就已经确定将该对象存储到String Pool中了。因此,String s = “abc”只会在编译期,在String Pool中创建一个对象。 例如: Java代码 1. Strings1=abc; 2. Strings2=abc; 3. System.out.println(s1=s2);/true结果说明:JVM创建了两个引用str1和str2,但在String Pool中只创建了一个对象
13、,而且两个引用都指向了同一个对象。 2、String s = new 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中已存在
14、的对象“abc”, 然后执行new String(“abc”)构造方法,在Heap里又创建一个新的字符串对象“abc”,并将引用s指向Heap中创建的新对象。 注意:使用new String(“”)创建的字符串对象时,会在运行期创建新对象存储到Heap中。因此,new String(“abc”)创建字符串对象时,会创建2个对象,编译期在String Pool中创建一个,运行时Heap中创建一个。 这里使用了 Java代码 1. publicString(Stringoriginal)这个构造方法,作用:初始化一个新创建的String对象,使其表示一个与参数相同的字符序列;换句话说,新创建的字符
15、串是该参数字符串的副本。 由于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=abcd
16、ef; 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
17、文件中就已经存在“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
18、.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. Str
19、ings5=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;
20、 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修饰的变量,它在编译时被解析为常量值的
21、一个本地拷贝存储到自己的常量池中或嵌入到它的字节码流中。所以此时的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.ou
22、t.println(s3=s5); 9. Java代码 1. privatestaticStringgetDef() 2. returndef; 3. 程序运行结果如下: false false 结果说明:JVM对于方法调用给字符串引用赋值的情况,引用指向字符串的值在编译期是无法确定的,只有在程序运行调用方法后,将方法的返回值“def”和“abc”动态连接并分配新地址赋值给s4,所以上述程序的结果都为false。 通过以上的例子可知: Java代码 1. Strings=a+b+c;等价于: Java代码 1. Strings=abc;编译期,直接优化,进行常量连接。 对于: Java代码 1
23、. 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. publicStringto
24、String() 2. /Createacopy,dontsharethearray 3. returnnewString(value,0,count); 4. 可以发现是通过new String(.)返回了一个String对象,也就是说在堆中创建了对象。这时候会不会在池中出现abc这个对象呢?(question还没解决) 生成String s的过程中,编译器使用sb执行的过程:创建一个StringBuffer对象,使用append()向此StringBuffer对象直接添加新的字符串(而不是每次制作一个新的副本)。 对于String c = c;String s = a + b + c;,编
25、译器将会先将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就不会作为编译时常量来运算了。相当于执行: String s = new Builder().append(a).append(b) .append(c) .toString(); 对于String b = b;Str
26、ing s = a + b + c;,这种形式的就没办法优化了,直接生成StringBuilder对象,然后调用三次 append()方法,即: String s = new Builder().append(a).append(b) .append(c) .toString(); 接着,我们再看以下代码: Java代码 1. Stringstr1=abc;/是字符串常量,它在编译期被确定,放在常量池中(共享内容值) 2. /newString()创建的字符串不放入常量池中 3. Stringstr2=newString(abc);/不是字符串常量,不在编译期确定(不共享内容值)Java代码
27、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. publicnativeS
28、tringintern();这是一个本地方法。在调用这个方法时,JAVA虚拟机首先检查String Pool中是否已经存在与该对象值相等对象存在,如果有则返回字符串池中对象的引用;如果没有,则先在String Pool中创建一个相同值的String对象,然后再将它的引用返回。 例程6: Java代码 1. publicclassTestString 2. publicstaticvoidmain(Stringargs) 3. Strings1=newString(abc);/语句1 4. Strings2=abc;/语句2 5. Strings3=newString(abc);/语句3 6.
29、System.out.println(s1=s2);/语句4 7. System.out.println(s1=s3);/语句5 8. System.out.println(s2=s3);/语句6 9. System.out.println(s1=s1.intern();/语句7 10. System.out.println(s2=s2.intern();/语句8 11. System.out.println(s1.intern()=s2.intern();/语句9 12. Stringhello=hello;/语句10 13. Stringhel=hel;/语句11 14. Stringlo
30、=lo;/语句12 15. System.out.println(hello=hello);/语句13 16. System.out.println(hello=hel+lo);/语句14 17. System.out.println(hello=hel+lo);/语句15 18. System.out.println(hello=hel+lo);/语句16 19. 20. 问题1:当执行完语句(1)时,在内存里面生成几个对象?它们是什么?在什么地方? 当执行完语句(1)时,在内存里面创建了两个对象,它们的内容分别都是abc,分别在String Pool(常量池)和Heap(堆)里。其字符串的
31、创建过程如下:首先在String Pool里面查找查找是否有 abc,如果有就直接使用,但这是本程序的第一条语句,故不存在一个对象abc,所以要在String Pool中生成一个对象abc,接下来,执行new String(abc)构造方法,new出来的对象都放在Heap里面。在Heap里又创建了一个abc的对象。这时内存里就有两个对象了,一个在String Pool 里面,一个在Heap里面。 问题2:当执行完语句(2)时,在内存里面一共有几个对象?它们是什么?在什么地方? 当执行完语句(2)时,在内存里面一个对象也没有创建。当我们定义语句(2)的时候,如果我们用字符串的常量值(字面值)给s
32、2赋值的话,那么首先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)赋值的话,那
33、么它首先是在String Pool里面去找有没有内容为abc的字符串对象存在,如果有的话,就不用创建新的对象,直接引用String Pool里面已经存在的对象;如果没有的话,就在 String Pool里面去创建一个新的对象,接着将引用指向这个新创建的对象。所以,当执行完语句(2)时内存里面一共有2个对象,它们的内容分别都是abc,在String Pool里面一个内容abc的对象,在Heap里面有一个内容为abc的对象。 问题3:当执行完语句(3)时,在内存里面一共有几个对象?它们是什么?在什么地方? 当执行完语句(3)时,其执行过程是这样的:它首先在String Pool里面去查找有没有内容
34、为abc的字符串对象存在,发现有这个对象存在,它就不去创建 一个新的对象。接着执行new.,只要在java里面有关键字new存在,不管内容是否相同,都表示它将生成一个新的对象,new多少次,就生成多少个对象,而且新生成的对象都是在Heap里面,所以它会在Heap里面生成一个内容为abc的对象,并且将它的地址赋给了引用s3,s3就指向刚在Heap里面生成的内容为abc的对象。所以,当执行完语句(3)时,内存里面一共有3个对象,其中包含了在String Pool里面一个内容为abc的字符串对象和在Heap里面包含了两个内容为abc的字符串对象。 问题4:当执行完语句(4)(5)(6)后,它们的结果
35、分别是什么? 在java里面,对象用=永远比较的是两个对象的内存地址,换句话说,是比较=左右两边的两个引用是否指向同一个对象。对于java里面的8种原生数据类型来说,=比较的是它们的字面值是不是一样的;对应用类型来说,比较的是它们的内存地址是不是一样的。在语句(1)(2)(3)中,由于s1、s2、s3指向不同的对象,它们的内存地址就不一样,因此可以说当执行完语句(4)(5)(6),它们返回的结果都是false。 问题5:当执行完语句(7)(8)(9)后,它们的结果分别是什么? 首先,s1这个对象指向的是堆中第一次new.生成的对象,当调用 intern 方法时,如果String Pool已经包
36、含一个等于此 String 对象的字符串(该对象由equals(Object)方法确定),则返回指向String Pool中的字符串对象的引用。因为String Pool中有内容为abc的对象,所以s1.intern()返回的是String Pool中的内容为abc的字符串对象的内存地址,而s1却是指向Heap上内容为abc的字符串对象的引用。因而,两个引用指向的对象不同,所以,s1 = s1.intern() 为false,即语句(7)结果为false。 对于s2.intern(),它还是会首先检查String Pool中是否有内容为abc的对象,发现有,则将String Pool中内容为a
37、bc的对象的地址赋给s2.intern()方法的返回值。因为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()方法的返回值。因为两者返回的地址都指
38、向同一个对象,所以,s1.intern() = s2.intern()的结果为true,,即是语句(9)结果为true。 因此,当执行完语句(7)(8)(9)后,它们的结果分别是false、true、true。 问题6:当执行完语句(13)(14) (15)(16)后,它们的结果分别是什么? hello = hello引用hello指向的对象就是String Pool中的“hello”,即语句(13)的结果为true。 hello = hel + lo当加号两边都是常量值时,就会组成一个新的常量值hello在String Pool里面,如果String Pool已经有相同内容的就不会再创建,则
39、直接返回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=newStrin
40、g(abc); 4. s2.intern();/虽然执行了s2.intern(),但它的返回值没有赋给s2 5. s3=s3.intern();/把StringPool中“abc”的引用赋给s3 6. System.out.println(s1=s2); 7. System.out.println(s1=s2.intern(); 8. System.out.println(s1=s3);运行结果如下: false true true 结果说明:因为s2.intern()只是执行了,而没有把String Pool中的“abc”的地址赋给s2,所以s1还是指向String Pool中的“abc”,
41、s2则指向Heap中的“abc”,对于s1 = s2,返回值为false;对于s1 = s2.intern(),其中s2.intern()的返回值为指向String Pool中“abc”的地址,故s2.intern()与s1指向同一个对象,因而返回true;因为s3 = s3.intern()把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”,运行期确定。 注意:Stri
限制150内