1.使用类的静态字段和构造函数,可以跟踪某个类所创建对象的个数。请写一个类,在任何时候都可以向他查询“你已经创建了几个对象”
1 package 第四五周; 2 3 public class Duixiangshu { 4 private static int n; 5 6 public Duixiangshu() 7 { 8 n++; 9 }//构造函数 10 11 public static int value() 12 { 13 return n; 14 } 15 16 public static void main(String[] args) { 17 // TODO 自动生成的方法存根 18 Duixiangshu a1=new Duixiangshu(); 19 Duixiangshu a2=new Duixiangshu(); 20 Duixiangshu a3=new Duixiangshu(); 21 Duixiangshu a4=new Duixiangshu(); 22 Duixiangshu a5=new Duixiangshu(); 23 System.out.println("已创建对象个数为 :"+Duixiangshu.value()); 24 } 25 26 }
运行结果:
2. 静态方法中只允许访问静态数据,那么,如何在静态方法中访问类的实例成员,请编写代码验证你的猜想。
1 package 第四五周; 2 3 public class Shilibianliang { 4 int x=3; 5 static int y=4; 6 public static void main(String[] args) { 7 // TODO 自动生成的方法存根 8 Shilibianliang sl=new Shilibianliang(); 9 System.out.println("实例成员"+sl.x); 10 System.out.println("静态成员"+y); 11 } 12 13 }
运行截图:
3.以下代码为何通不过编译
解答:
因为Foo类中自行定义了构造函数,而且是有参数的构造函数,但在主函数创建对象的却没有参数,导致无法创建对象,无法对其进行初始化,所以
没有通过编译。若自行定义构造函数,则创造对象时参数必须匹配。
4.请运行下列示例,观察输出结果,总结出“静态初始化块的执行顺序”。
1 package 第四五周; 2 3 class Root 4 { 5 static{ 6 System.out.println("Root的静态初始化块"); 7 } 8 { 9 System.out.println("Root的普通初始化块"); 10 } 11 public Root() 12 { 13 System.out.println("Root的无参数的构造器"); 14 } 15 } 16 class Mid extends Root 17 { 18 static{ 19 System.out.println("Mid的静态初始化块"); 20 } 21 { 22 System.out.println("Mid的普通初始化块"); 23 } 24 public Mid() 25 { 26 System.out.println("Mid的无参数的构造器"); 27 } 28 public Mid(String msg) 29 { 30 //通过this调用同一类中重载的构造器 31 this(); 32 System.out.println("Mid的带参数构造器,其参数值:" + msg); 33 } 34 } 35 class Leaf extends Mid 36 { 37 static{ 38 System.out.println("Leaf的静态初始化块"); 39 } 40 { 41 System.out.println("Leaf的普通初始化块"); 42 } 43 public Leaf() 44 { 45 //通过super调用父类中有一个字符串参数的构造器 46 super("Java初始化顺序演示"); 47 System.out.println("执行Leaf的构造器"); 48 } 49 50 } 51 52 public class Chushihua { 53 54 public static void main(String[] args) { 55 // TODO 自动生成的方法存根 56 new Leaf(); 57 } 58 59 }
运行截图:
总结:
先执行静态初始化块,再依次执行每个类的普通块和构造器。
5.请依据代码运行结果,自行总结Java字段初始化的规律。
1 package 第四五周; 2 3 class InitializeBlockClass 4 { 5 { 6 filed =200; 7 }//初始化块 8 public int filed =100; 9 public InitializeBlockClass(int value) 10 { 11 this.filed=value; 12 }//带参数的构造函数 13 public InitializeBlockClass() 14 { 15 16 }//不带函数的构造函数 17 } 18 public class Chushihuakuai { 19 20 public static void main(String[] args) { 21 // TODO 自动生成的方法存根 22 InitializeBlockClass a=new InitializeBlockClass(); 23 System.out.println("filed = :"+a.filed); 24 InitializeBlockClass b=new InitializeBlockClass(300); 25 System.out.println("filed = :"+b.filed); 26 } 27 28 }
运行截图:
总结:
若构造有参数的对象,则调用有参数的构造函数,成员数值由构造函数中的函数体决定。如果调用没有参数的构造函数,成员数值由初始化块外的语句决定,
如果初始化块外没有赋值语句,则以初始化块决定。