黑马程序员技术交流社区
标题:
静态初始化顺序
[打印本页]
作者:
李力
时间:
2013-4-3 13:28
标题:
静态初始化顺序
class Cup
{
Cup(int marker)
{
System.out.println("Cup("+marker+")");
}
void f(int marker)
{
System.out.println("f("+marker+")");
}
}
class Cups
{
static Cup cup1;
static Cup cup2;
static
{
cup1 = new Cup(1);
cup2 = new Cup(2);
}
Cups()
{
System.out.println("Cups()");
}
}
public class Test
{
public static void main(String[] args)
{
System.out.println("Inside main()");
Cups.cup1.f(99);
}
static Cups cup1 = new Cups();
static Cups cup2 = new Cups();
}
运行结果:
Cup(1)
Cup(2)
Cups()
Cups()
INside main()
f(99)
怎么会这样呢?请大神指教!
作者:
邵震
时间:
2013-4-3 13:42
个人感觉是你的15 16行出错了 要不就是最后两行出错了
我刚看到这里 能看懂 但是看不出有啥毛病
作者:
刘胜寒
时间:
2013-4-3 13:49
首先你要明确这么一个东西。
被static修饰的东西是属于类的东西,也就是说在编辑期就会被创建。
你要执行
public class Test
{
public static void main(String[] args)
{
System.out.println("Inside main()");
Cups.cup1.f(99);
}
static Cups cup1 = new Cups();
static Cups cup2 = new Cups();
}
复制代码
首先会首先执行
static Cups cup1 = new Cups();
执行这条语句时;
static Cups cup1 = new Cups();
回去调用在堆内存生成好的Cpus.class文件,所以会
输出
Cup(1)
Cup(2)
Cpp()
这么三个东西。
然后再去执行
static Cups cup2 = new Cups();
这条语句,
因为
class Cups
{
static Cup cup1;
static Cup cup2;
static
{
cup1 = new Cup(1);
cup2 = new Cup(2);
}
Cups()
{
System.out.println("Cups()");
}
}
复制代码
因为这个类中的class文件,已经存在于堆内存中,就不会去执行这个类的静态代码块。
所以会输出
Cups()
然后开始执行
public static void main(String[] args)
{
System.out.println("Inside main()");
Cups.cup1.f(99);
}
首先输出INside main();
然后去z执行Cups.cup1.f(99);
输出f(99);
你可以在Cup中添加一个静态代码块,里面写一个System.out.println("Cup First");
则你的运行结果的第一句一定是“Cup First”;
作者:
宋耀冬
时间:
2013-4-3 13:56
static 关键字
static(静态)关键字用于修饰成员(成员变量和成员函数).
被修饰后的成员具备以下特点:随着类的加载而加载,优先于对象存在,被所有对象所共享,可以被类名直接调用。
作者:
张源锋
时间:
2013-4-3 14:09
本帖最后由 无奈№追夜 于 2013-4-3 14:12 编辑
当程序执行的时候首初始化静态的语句,这个程序的执行顺序是:static Cups cup1 = new Cups();—— static Cup cup1;
static Cup cup2;——到static语句块里的cup1 = new Cup(1);——调用cup的构造方法,这时会打印出
Cup(1)
——到static语句块里的cup2 = new Cup(2);——调用cup的构造方法,这里打印
Cup(2)
——这里到Cups构造方法 Cups(){System.out.println("Cups()"); }这里会打印
Cups()
——static Cups cup2 = new Cups();——这时Cups里的所有静态语句都不会被重新执行,因为静态的东西只被初始化一次,因此直接调用Cups构造方法 Cups(){System.out.println("Cups()"); }这里会打印
Cups()
—— main方法时面的语句System.out.println("Inside main()");打印
Inside main()
——Cups.cup1.f(99);调用f这个方法打印出
f(99)
作者:
齐静
时间:
2013-4-3 14:15
Test 类加载时首先执行被static修饰的成员
static Cups cup1 = new Cups();
static Cups cup2 = new Cups();
执行static Cups cup1 = new Cups();调用Cups类对其初始化
Cups类加载进来时也是先执行被static修饰的成员
static Cup cup1
static Cup cup2
结果为:
Cup(1)
Cup(2)
再调用构造函数对对应的对象初始化
结果:Cups()
由于静态代码存在于方法区中,只初始化一次。
所以在执行static Cups cup2 = new Cups(); 时static Cup cup1 static Cup cup2 将不再被初始化, 这条语句输出的结果只有构造函数对cup2初始化的结果 :Cups()
最后在类都加载完成后执行main中的打印语句结果为:Inside main() f(99)
作者:
刘策
时间:
2013-4-3 14:20
静态代码块随着类的加载只执行一次
作者:
奋斗2013
时间:
2013-4-3 14:51
本帖最后由 奋斗2013 于 2013-4-3 14:53 编辑
你在main主线程中只进行了如下操作:
public static void main(String[] args)
{
System.out.println("Inside main()");//输出Inside main()
Cups.cup1.f(99);//这句似乎有问题。
}
static 修饰的静态类,不用实例化对象就可直接调用其里面的方法。
被static修饰的成员变量和成员方法独立于该类的任何对象。也就是说他不依赖于类的特定实例,被类的所有实例共享。
只要这个类被加载,JAVA 虚拟机就能根据类名在运行是数据区内找到他们。因此static对象可以在他创建的任何对象之前访问他们。
作者:
田光峰
时间:
2013-4-3 15:18
当执行Test类时 就会加载Test.class文件 会执行他的
static Cups cup1 = new Cups();
当new Cups() 是会加载Cups.class文件并执行他静态语句块
static
{
cup1 = new Cup(1);
cup2 = new Cup(2);
}
就会加载Cup.class文件执行他的构造函数输出结果是Cup(1) Cup(2)
然后执行Cups类构造函数 结果是Cup()
执行 static Cups cup2 = new Cups();时是不执行静态语句块和静方法的因为第一次已执行过,
所以结果是Cup()
然后是 System.out.println("Inside main()");
Cups.cup1.f(99);
结果是INside main()
f(99)
综上结果为:
Cup(1)
Cup(2)
Cups()
Cups()
INside main()
f(99)
作者:
李力
时间:
2013-4-3 17:06
谢谢各位!
作者:
邵彩华
时间:
2013-4-3 18:38
鉴于前面各楼层的友友们已经回答的很晚上了,我在这儿只补充说明一点前面没有提到的,一面楼主可以更详细的理解类的加载过程。
1,类加载时,是先加载静态成员的,并按代码顺序进行类的静态初始化。然后才从主函数开始执行的。
2,如果把Cups里面的cup1,cup2给初始化,即改为:
static Cup cup1= new Cup(88);
static
{
cup1 = new Cup(1);
cup2 = new Cup(2);
}
static Cup cup2= new Cup(88);
复制代码
则执行结果就是:
Cup(88)
Cup(1)
Cup(2)
Cup(88)
Cups()
Cups()
Inside main()
f(99)
3.类的加载和静态初始化只有一次。
作者:
邵彩华
时间:
2013-4-3 19:12
鉴于前面各楼层的友友们已经回答的很完善了,我在这儿只补充说明一点前面没有提到的,以便楼主更详细的理解类的加载过程。
1,类加载时,是先加载静态成员的,并按代码顺序进行类的静态初始化。然后才从主函数开始执行的。
2,如果把Cups里面的cup1,cup2给初始化,即改为:
复制代码
则执行结果就是:
static Cup cup1= new Cup(88);
static
{
cup1 = new Cup(1);
cup2 = new Cup(2);
}
static Cup cup2= new Cup(88);
复制代码
执行结果:
Cup(88)
Cup(1)
Cup(2)
Cup(88)
Cups()
Cups()
Inside main()
f(99)
复制代码
3.类的加载和静态初始化只有一次。
详细执行过程如下:
用java命令运行Test时,先加载Test.clss;然后对静态成员cup1初始化,加载Cups.class(如果此处之声明Cups 类型成员cup1而没有等号右边的初始化语句,就不会加载Cups类);Cups类加载过程中,按顺序做静态初始化,先是cup1/cup2,但因为只声明而没有初始化语句故跳过,继续执行static静态代码块初始化;调用了Cup类,故再将Cup.class加载进来,调用Cup(int maker)分别对cup1,cup2进行初始化,打印出Cup1 Cup2; 然后调用构造函数Cups(),打印出Cups(),至此,Test中的cup1已经初始化完毕。开始初始化cup2,因为Cups已经加载进内存,所以可以直接调用构造方法Cups(),打印出Cups(),Test中的cup2初始化完毕。这是才开始执行main()函数。后面的执行顺序楼主都懂,此处省略。
作者:
打工人
时间:
2013-4-4 16:36
若还有问题,继续追问; 没有的话,尽量及时将帖子分类改成【已解决】~
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2