public static void main(String[] args)...{
System.out.println("Yao想参加奥运会");
}
static American american = new American();
}
class American ... {
American()...{
System.out.println("American不希望Yao参加奥运会");
}
}
执行结果:
American不希望Yao参加奥运会
Yao想参加奥运会
按照顺序执行的规则,结果应该是:
Yao想参加奥运会
American不希望Yao参加奥运会
才对啊?这个怎么回事??
ps:如果American american = new American();放在main里边,就是顺序执行了
解释:
程序在编译的时候对代码中所有的类,都会生成对应的.class文件.
程序在执行的时候会加载所有的.class文件(包括import导入的.class文件和extends继承来的父类.class文件)。
然后是进行优化,这个就是为什么有的时候第一次运行的时候会比较慢,以后的时候会很快.
当这一切都完成后,程序进行初始化工作,先初始化static成员(变量,对象or对象的引用),因为要保证所有的变量和引用在使用的时候都要初始化,当然先初始化static成员.
先初始化static成员是java实现这种保证的具体方法。
当然不是所有class中的static变量都在第一次被初始化,对于单独的class中的static变量或者是对象引用等到比如new 一个的时候才进行初始化
static初始化完成以后才进行构造器的初始化,用默认的或者是你自己覆盖的构造器.
在这个例子中因为Yao类中有一个static引用变量,所以先初始化static引用.
然而这是new一个American的class,而且这个class里面没有static成员,所以就调用构造器American(){}进行对american初始化
当这一切都进行结束后才进行main方法里面的输出,所以结果是...
ps:对于代码static American american = new American();
new American()错误:不能在方法体外直接定义堆内存,一定要有栈内存引用才可以(Syntax error on token "new", delete this token).
American american = new American()不错但有bug:american的引用是非静态的,所以在没有创建对象时是无法调用American类的构造方法的.
所以改为:static American american = new American();才可以println出"American不希望Yao参加奥运会".
再给个例子:
public static void main(String[] args)...{
int a = 1;
System.out.println("a = " + a + ";b = " + b);//报错:b cannot be resolved
int b = 2;
}
}
class shunxu2 ... {
static int a = 1;
public static void main(String[] args)...{
System.out.println("a = " + a + ";b = " + b);
}
static int b = 2;
}