如下有3个类,其中COM是表示组件类别。Root类包含一个COM对象引用,Root中派生出Stem类(即Stem类继承Root类)。每个类都有一个无参数的构造函数,打印当前的类名。其中Root类中拥有一个静态代码块。
package com.practise;
public class Try
{
public static void main(String[] args)
{
new Root();
new Root();
new Stem();
}
}
class Root
{
Root(){System.out.println("this is Root");}
static
{
System.out.println("我是静态的");
//静态变量是属于类的,而不是属于类创建的对象或实例。
//因为静态变量被类的所有实例共用,所以非线程安全的。
//通常静态变量还和关键字final一起用,作为所有对象共用的资源或常量。
}
COM c;
}
class Stem extends Root
{
Stem(){System.out.println("this is Stem");}
COM c=new COM("Stem");
}
class COM
{
COM(String s){System.out.println("我是COM-----"+s);}
}
编译运行这个段代码,可以得到如下结果:
/*output:
我是静态的
this is Root
this is Root
this is Root
我是COM-----Stem
this is Stem
*/
得到这个结果的原因是什么呢?首先从类的加载来分析,加载类文件名相同的public类,找到主函数,然后有new Root();此时需要实例化一个Root对象。
实例化Root对象时,首先应该执行静态代码块,静态方法,静态变量(需要注意的是静态代码块或者方法以及变量,只会随着类的加载而只执行一次!而且是所有对象共用的资源或常量),然后申明类中非静态成员变量,再执行构造函数,因为构造函数中可能会使用类中的成员变量。于是第一行便是打印了“我是静态的”,接着是“this is Root”
第二次实例化Root对象时,便不再执行静态代码块,于是便申明一个COM类,存在栈中,初始化为null,最后执行构造函数,打印“this is Root”。
第三次是实例化一个Stem对象,在创建Stem对象时,通过extends关键字发现它拥有基类Root,此时应该转到先实例化Stem的基类Root!!因为在继承关系中,子类继承了父类中的所有成员变量和方法,依赖于父类,(其实每个子类都拥有父类的内置对象),实例化Root类和上面一样,创建COM对象,引用为null存在栈中(由于Root类在之前已经进行了两次实例化,所以不会再执行静态代码块,所以的静态代码块都只加载一次),执行构造函数打印“this is Root”。
然后再创建Stem对象,类中无静态成员,于是先申明成员变量,COM c= new COM(),这个语句表明在申明变量的时候同时也进行了初始化,不再是null!由打印了“我是COM---Stem‘可以看出执行了初始化。然后再是构造函数,打印了”this is Stem“。
Java还只算得上是初学者,以上仅是个人在学习过程中的一些理解。欢迎各位发现错误并帮助我改正。希望自己better and better!