动手动脑及课后实验问题2

进行试验

 1 class InitializeBlockClass{
 2     {
 3         field =200;
 4     }
 5     public int field =100;
 6     public InitializeBlockClass(int valve){
 7         this.field=valve;
 8     }
 9     public InitializeBlockClass(){
10         
11     }
12 }
13 public class Test {
14 
15     public static void main(String[] args) {
16         InitializeBlockClass obj =new InitializeBlockClass();
17         System.out.println(obj.field);
18         
19         obj =new InitializeBlockClass(300);
20         System.out.println(obj.field);
21 
22     }
23 
24 }

请依据代码的输出结果,自行总结Java字段初始化的规律。

初始化顺序:

1.执行类成员定义时指定的默认值或类的初始化块,到底执行哪一个要看哪一个“排在前面”。

2.执行类的构造函数:类的初始化块不接收任何的参数,而且只要一创建类的对象,它们就会被执行。因此,适合于封装那些“对象创建时必须执行的代码”。

初始化模板:

Java进行初始化的地方有两个:初始化块和构造函数,其中初始化块又分为静态初始化块和实例初始化块。静态初始化块是类中由static修饰的初始化块,实例初始化块为类中没有任何关键字修饰的初始化语句。

如果在主函数中创建对象时没有形参时,如果在类中定义了公共的变量并给与了赋值,那么就会把值赋给主函数中的变量,再调用类中的默认构造函数,如果在主函数中创建对象时有形参,则调用类中对应的构造函数。

动手动脑

当多个类之间有继承关系时,创建子类对象会导致父类初始化块的执行。请自行编写示例代码验证结论
 1 class Student//父类
 2 {
 3     String name;
 4     {    name="LI"; }
 5 }
 6 //子类继承父类
 7 class Teacher extends Student{
 8     int age=20;
 9     float wage =10000;
10     void show()
11     {
12         System.out.println("姓名:"+name);
13         System.out.println("年龄:"+age);
14         System.out.println("工资:"+wage);
15     }
16 }
17 public class Inherit {
18     public static void main(String[] args){
19 
20         Teacher teacher = new Teacher();
21         teacher.show();
22         }
23 }

动手动脑2

请运行TestStaticInitializeBlock.java示例,观察输出结果,总结出“静态初始化块的执行顺序”。
 1 class Root
 2 {
 3     static{
 4         System.out.println("Root的静态初始化块");
 5     }
 6     {
 7         System.out.println("Root的普通初始化块");
 8     }
 9     public Root()
10     {
11         System.out.println("Root的无参数的构造器");
12     }
13 }
14 class Mid extends Root
15 {
16     static{
17         System.out.println("Mid的静态初始化块");
18     }
19     {
20         System.out.println("Mid的普通初始化块");
21     }
22     public Mid()
23     {
24         System.out.println("Mid的无参数的构造器");
25     }
26     public Mid(String msg)
27     {
28         //通过this调用同一类中重载的构造器
29         this();
30         System.out.println("Mid的带参数构造器,其参数值:" + msg);
31     }
32 }
33 class Leaf extends Mid
34 {
35     static{
36         System.out.println("Leaf的静态初始化块");
37     }
38     {
39         System.out.println("Leaf的普通初始化块");
40     }    
41     public Leaf()
42     {
43         //通过super调用父类中有一个字符串参数的构造器
44         super("Java初始化顺序演示");
45         System.out.println("执行Leaf的构造器");
46     }
47 
48 }
49 
50 public class TestStaticInitializeBlock
51 {
52     public static void main(String[] args) 
53     {
54         new Leaf();
55         
56 
57     }
58 }

如果定义初始化块时使用了static修饰符,则变成了静态初始化块。静态初始化块时类相关的,系统将在类初始化阶段执行静态初始化块,而不是在创建对象时才执行。

因此静态初始化块总是比普通初始化块先执行。

 与普通初始化块类似的是,系统在类初始化阶段执行静态初始化块时,不仅会执行本类的静态初始化块,而且还会一直上溯到 java.lang.Object类,先执行java.lang.Object类中的静态初始化块,然后执行其父类的静态初始化块,最后才执行该类的静态 初始化块。经过这个过程,才完成了该类的初始化过程。只有当类初始化完成后,才可以在系统中使用这个类,包括访问类method、类Field,或者用这个类来创建实例。

 一个有趣的问题

静态方法中只允许访问静态数据,那么,如何在静态方法中访问类的实例成员(即没有附加static关键字的字段或方法)?

请编写代码验证你的想法。

 1 class Exercise{
 2 
 3     int a=0;
 4     static int b;
 5     static public int getb(int newb)
 6     {
 7         b=newb;
 8         System.out.println(b);
 9         return b;
10     }
11 
12     public int num()
13     {
14         int a=1;
15         return a;
16     }
17 }
18 
19 public class Test2 {
20 
21     public static void main(String[] args){
22 
23         Exercise e=new Exercise();
24 
25         e.getb(1111);
26 
27         e.num();
28     }
29 
30 }

????????????

课后作业

使用类的静态字段和构造函数,我们可以跟踪某个类所创建对象的个数。请写一个类,在任何时候都可以向它查询“你已经创建了多少个对象?”

 1 public class Count {
 2     public static int number; 
 3     public Count()
 4     {
 5         number ++; //统计个数,每创建一个类, number++
 6     }
 7     
 8     public static int getValue()
 9     {
10         return number;  //返回得到number的最终的值
11     }
12     
13     public static void main (String args[])
14     {
15         Count c1 = new Count();
16         Count c2 = new Count();
17         Count c3 = new Count();
18         Count c4 = new Count();
19         System.out.println("创建对象的个数是:"+Count.getValue());
20     }
21 }

 
原文地址:https://www.cnblogs.com/ljz-2014/p/4887907.html