03-类与方法
一、如果一个类中既有初始化块,又有构造方法,同时还设定了字段的初始值,谁说了算?以下代码输出结果是什么?
请依据代码的输出结果,自行总结Java字段初始化的规律。
执行结果:
当“public int field=100;”在“{field=200;}”之前时,field初始化数值是由“{field=200;}”说了算;当“public int field=100;”在“{field=200;}”之后时,field初始化数值是由“public int field=100;”说了算。也就是说,那句话在后边,后执行,则哪句话说了算。
注:类字段的初始化顺序
- 执行类成员定义时指定的默认值或类的初始化块,到底执行哪一个要看哪一个“排在前面”。
- 执行类的构造函数。。
类的初始化块不接收任何的参数,而且只要一创建类的对象,它们就会被执行。因此,适合于封装那些“对象创建时必须执行的代码”。
二、请运行TestStaticInitializeBlock.java示例,观察输出结果,总结出“静态初始化块的执行顺序”。
代码:
1 package shiyan3; 2 class InitializeBlockClass { 3 { 4 field=200; 5 } 6 public int field=100; 7 public InitializeBlockClass(int value) 8 { 9 this.field=value; 10 } 11 12 public InitializeBlockClass() 13 { 14 15 } 16 17 public static void main(String[] args) { 18 // TODO Auto-generated method stub 19 InitializeBlockClass obj=new InitializeBlockClass(); 20 System.out.println(obj.field); 21 22 obj=new InitializeBlockClass(300); 23 System.out.println(obj.field); 24 } 25 }
执行结果:
静态初始化块的执行顺序:
(1) 先执行静态初始化块,再执行普通方法。静态初始化块只执行一次。
(2) 创建子类型的对象时,也会导致父类型的静态初始化块的执行。
三、一个有趣的问题
静态方法中只允许访问静态数据,那么,如何在静态方法中访问类的实例成员(即没有附加static关键字的字段或方法)?
请编写代码验证你的想法。
1 package shiyan3; 2 public class Example 3 { 4 static int x = 1;//类的静态变量,初始化值为4 5 int y = 2; //类的实例变量,初始化值为3 6 public static void method()//静态方法 7 { 8 System.out.println("静态变量x = " + x);//在静态方法中可直接访问类的静态变量 9 System.out.println("实例变量y = " + new Example().y);//在静态方法中访问类的实例变量需首先进行类的实例化 10 } 11 12 public static void main(String[] args) 13 { 14 Example.method(); 15 Example xm = new Example(); 16 System.out.println("y = " + xm.y); 17 } 18 }
四、神奇代码
两对整数明明完全一样,为何一个输出true,一个输出false?
提示:
使用javap来分析生成class文件,看它调用了Interger类的哪个方法,然后打开JDK源文件查看源码,就可以找到答案。
Integer=100; 实际上调用的是Integer.valueOf(int i);
因为从-127到128之间的Integer数,Java在Integer中有事先缓存好的原型对象,每次返回的都是同一个Integer对象,只有不在这个范围的数才会新创建出一个Integer,最后所指都不是同一个对象,所以比较的不是同一个对象。
五、使用类的静态字段和构造函数,我们可以跟踪某个类所创建对象的个数。请写一个类,在任何时候都可以向它查询“你已经创建了多少个对象?”。
设计思想:
每次执行分为3个选择:1-创建对象,2-查询已创建对象个数,3-退出。
若选择1,之后要输入创建的对象个数,以对象数组的形式创建,程序循环,每次创建的对象数依次累加。
若选择2,可随时查询已经创建的对象个数。
若选择3,可随时退出。
代码:
1 package shiyan3; 2 //信1605-2 20163588 王金萱 3 import java.util.Scanner; 4 public class countDuixiang { 5 public static void main(String[] args) 6 { 7 Duixiang oo=new Duixiang(); 8 oo.f(); 9 } 10 } 11 class Duixiang 12 { 13 static int n; 14 static int count; 15 public Duixiang() 16 { 17 count=n; 18 } 19 public void f() 20 { 21 int j=0; 22 Scanner in=new Scanner(System.in); 23 do 24 { 25 System.out.println("1-创建对象 2-查询已创建对象个数 3-退出"); 26 j=in.nextInt(); 27 if(j==1) 28 { 29 System.out.print("请输入要创建的对象个数:"); 30 int m=in.nextInt(); 31 Duixiang d[]=new Duixiang[m]; 32 n+=m; 33 Duixiang w3=new Duixiang(); 34 System.out.println("创建成功!"); 35 } 36 if(j==2) 37 { 38 System.out.println("你已经创建了"+Duixiang.count+"个对象"); 39 } 40 }while(j!=3); 41 } 42 }
执行结果: