求大神过来看看这条题目。。。

lollipop1993 2015-03-20 11:40:18
package Test_01;


public class Test {
public static int a = 0;


static {
a = 10;
System.out.println("静态代码块在执行a=" + a);
}

{
a = 8;
System.out.println("非静态代码块在执行a=" + a);
}



public Test() {
this("带参构造方法在执行a="+a); // 调用另外一个构造方法
System.out.println("无参构造方法在执行a=" + a);
}


public Test(String n) {
System.out.println(n);
}


public static void main(String[] args) {
Test t = null;
System.out.println("!!!!!!!!!!!!!!!!!!!!!");
t = new Test();
}


}



输出结果是:
静态代码块在执行a=10
!!!!!!!!!!!!!!!!!!!!!
非静态代码块在执行a=8
带参构造方法在执行a=10
无参构造方法在执行a=8


我想问一下,为什么“带参构造方法在执行a=10”这一条语句输出的不是8而是10?
...全文
755 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
阿娜达 2015-03-20
  • 打赏
  • 举报
回复
因为static 第一个代码块的前面加了static 也就是说第一个是一个静态的代码块,那么在Text这个类一加载时 ,他首先运行,而没有加static的代码块 只会在这个类创建对象时随之运行 这就是考了一个静态static的运行方式
廿二又 2015-03-20
  • 打赏
  • 举报
回复
乖乖能分清楚这些值得指向真不简单 ,学习了
结贴是美德 2015-03-20
  • 打赏
  • 举报
回复
都快淡忘了,感谢此贴的所有人
hongbucai 2015-03-20
  • 打赏
  • 举报
回复
引用 15 楼 lollipop1993 的回复:
[quote=引用 10 楼 hongbucai 的回复:] 静态代码之所以优先非静态的,是因为被static修饰的成员都是类成员,会随着JVM加载类的时候加载而执行,而没有被static修饰的成员也被称为实例成员,需要创建对象才会随之加载到堆内存。所以静态的会优先非静态的。 构造方法里的构造代码块优先于构造方法的方法体,但是this关键字跟super关键字不能同时出现,而且只能在代码的第一行。如果出现了this关键字,隐式三步就不会执行,隐式三步我上面有讲。 其中隐式三步包含构造代码块。 这样就会在被调用的其他构造方法在执行隐式三步的时候,去执行构造代码块。 其实有个很简单的测试方法。你随便写个类,类中有3个变量,然后写3个构造方法,三个参数的构造方法去调用两个参数的构造方法,然后两个参数的再去调用一个参数的构造方法。 然后在写个构造代码块,然后在创建个对象传递三个参数,这样你会发现其实构造代码块只执行了一次。只在最后被调用的构造方法执行了隐式三步,然后执行了构造代码块。
也就是说当多个构造方法被调用的时候,构造代码块,只会在最后的那个构造方法执行之前执行!十分感谢!![/quote]是的,因为我是初学者我扣的比较深,楼上有工作过的,认为开发中用的不多,建议没必要深究。
lollipop1993 2015-03-20
  • 打赏
  • 举报
回复
引用 10 楼 hongbucai 的回复:
静态代码之所以优先非静态的,是因为被static修饰的成员都是类成员,会随着JVM加载类的时候加载而执行,而没有被static修饰的成员也被称为实例成员,需要创建对象才会随之加载到堆内存。所以静态的会优先非静态的。 构造方法里的构造代码块优先于构造方法的方法体,但是this关键字跟super关键字不能同时出现,而且只能在代码的第一行。如果出现了this关键字,隐式三步就不会执行,隐式三步我上面有讲。 其中隐式三步包含构造代码块。 这样就会在被调用的其他构造方法在执行隐式三步的时候,去执行构造代码块。 其实有个很简单的测试方法。你随便写个类,类中有3个变量,然后写3个构造方法,三个参数的构造方法去调用两个参数的构造方法,然后两个参数的再去调用一个参数的构造方法。 然后在写个构造代码块,然后在创建个对象传递三个参数,这样你会发现其实构造代码块只执行了一次。只在最后被调用的构造方法执行了隐式三步,然后执行了构造代码块。
也就是说当多个构造方法被调用的时候,构造代码块,只会在最后的那个构造方法执行之前执行!十分感谢!!
三刀飞 2015-03-20
  • 打赏
  • 举报
回复
由于过程比较复杂,用图给你说明一下吧,对于静态代码块什么时候执行,不是重点,所以不深入研究
skgary 2015-03-20
  • 打赏
  • 举报
回复
http://docs.oracle.com/javase/specs/jls/se7/jls7.pdf 还是直接看这个文档中的相关章节,解释的一清二楚。
wyc_ 2015-03-20
  • 打赏
  • 举报
回复
看一下JVM中<init>函数的组成部分,解释的非常清楚了.
skgary 2015-03-20
  • 打赏
  • 举报
回复
引用 8 楼 lollipop1993 的回复:
[quote=引用 5 楼 hongbucai 的回复:] 虽然我是个菜鸟,但是楼上两位肯定没看仔细。 首先编译时肯定能编译过的,再其次为什么这样? 因为执行构造器(构造方法)的时候,在执行方法体之前存在隐式三步:1,super语句;2,显式初始化非静态变量,3,构造代码块。 你这里的第一个构造方法,因为用了this关键字(有this关键字,就不可以使用super关键字,所以隐式三步也不会执行,直接转到调用的构造方法),且参数类型是String,调用到有参的构造方法。此时传递的String是:“带参构造方法在执行a=10”;因为此时的a还是10,还没有执行到构造代码块中 a=8;这个语句,所以a不是8。接着在有参构造方法里才会执行构造代码块,也就是重新将a赋值为8。 以上就是为什么a为10,为什么不是8的原因。
你好,那么就是说 用了this调用另外一个构造之后,就不会去走构造代码块? 不是 静态代码 优先于构造代码块,构造代码块优先于构造方法的吗? 根据这个,我觉得是走了构造代码块,然后再走第一个构造方法这样的,难道我理解错了? 求指教。[/quote] 执行顺序 1. 静态代码块(不需要任何new,只要出现引用 就会调用) 2. 构造函数(new的时候调用) 3. 构造代码块(我个人从来没有用过这种方法写代码。。。。不好意思,所以认为编译不过) 4. 被调用的带参数构造代码
hongbucai 2015-03-20
  • 打赏
  • 举报
回复
静态代码之所以优先非静态的,是因为被static修饰的成员都是类成员,会随着JVM加载类的时候加载而执行,而没有被static修饰的成员也被称为实例成员,需要创建对象才会随之加载到堆内存。所以静态的会优先非静态的。 构造方法里的构造代码块优先于构造方法的方法体,但是this关键字跟super关键字不能同时出现,而且只能在代码的第一行。如果出现了this关键字,隐式三步就不会执行,隐式三步我上面有讲。 其中隐式三步包含构造代码块。 这样就会在被调用的其他构造方法在执行隐式三步的时候,去执行构造代码块。 其实有个很简单的测试方法。你随便写个类,类中有3个变量,然后写3个构造方法,三个参数的构造方法去调用两个参数的构造方法,然后两个参数的再去调用一个参数的构造方法。 然后在写个构造代码块,然后在创建个对象传递三个参数,这样你会发现其实构造代码块只执行了一次。只在最后被调用的构造方法执行了隐式三步,然后执行了构造代码块。
lollipop1993 2015-03-20
  • 打赏
  • 举报
回复
引用 7 楼 skgary 的回复:
楼主,debug一下就好了,非静态的代码块在构造函数之后运行。
你好,请看看8楼我的回复,我这样理解有问题吗?
lollipop1993 2015-03-20
  • 打赏
  • 举报
回复
引用 5 楼 hongbucai 的回复:
虽然我是个菜鸟,但是楼上两位肯定没看仔细。 首先编译时肯定能编译过的,再其次为什么这样? 因为执行构造器(构造方法)的时候,在执行方法体之前存在隐式三步:1,super语句;2,显式初始化非静态变量,3,构造代码块。 你这里的第一个构造方法,因为用了this关键字(有this关键字,就不可以使用super关键字,所以隐式三步也不会执行,直接转到调用的构造方法),且参数类型是String,调用到有参的构造方法。此时传递的String是:“带参构造方法在执行a=10”;因为此时的a还是10,还没有执行到构造代码块中 a=8;这个语句,所以a不是8。接着在有参构造方法里才会执行构造代码块,也就是重新将a赋值为8。 以上就是为什么a为10,为什么不是8的原因。
你好,那么就是说 用了this调用另外一个构造之后,就不会去走构造代码块? 不是 静态代码 优先于构造代码块,构造代码块优先于构造方法的吗? 根据这个,我觉得是走了构造代码块,然后再走第一个构造方法这样的,难道我理解错了? 求指教。
skgary 2015-03-20
  • 打赏
  • 举报
回复
楼主,debug一下就好了,非静态的代码块在构造函数之后运行。
lollipop1993 2015-03-20
  • 打赏
  • 举报
回复
引用 1 楼 qq_24224369 的回复:
因为static 第一个代码块的前面加了static 也就是说第一个是一个静态的代码块,那么在Text这个类一加载时 ,他首先运行,而没有加static的代码块 只会在这个类创建对象时随之运行 这就是考了一个静态static的运行方式
你好,我知道静态会随着类的加载而加载,但是我觉得,走了构造代码块之后,a的值不是8吗 然后通过this() 调了另外一个带String参数的构造 ,那么 a=8de值不是传过去了吗?为什么输出却是10?
hongbucai 2015-03-20
  • 打赏
  • 举报
回复
虽然我是个菜鸟,但是楼上两位肯定没看仔细。 首先编译时肯定能编译过的,再其次为什么这样? 因为执行构造器(构造方法)的时候,在执行方法体之前存在隐式三步:1,super语句;2,显式初始化非静态变量,3,构造代码块。 你这里的第一个构造方法,因为用了this关键字(有this关键字,就不可以使用super关键字,所以隐式三步也不会执行,直接转到调用的构造方法),且参数类型是String,调用到有参的构造方法。此时传递的String是:“带参构造方法在执行a=10”;因为此时的a还是10,还没有执行到构造代码块中 a=8;这个语句,所以a不是8。接着在有参构造方法里才会执行构造代码块,也就是重新将a赋值为8。 以上就是为什么a为10,为什么不是8的原因。
枫醉秋 2015-03-20
  • 打赏
  • 举报
回复
引用 2 楼 skgary 的回复:
你这能编译的过?!
这个代码肯定能编译通的
枫醉秋 2015-03-20
  • 打赏
  • 举报
回复
引用 1 楼 qq_24224369 的回复:
因为static 第一个代码块的前面加了static 也就是说第一个是一个静态的代码块,那么在Text这个类一加载时 ,他首先运行,而没有加static的代码块 只会在这个类创建对象时随之运行 这就是考了一个静态static的运行方式
+1
skgary 2015-03-20
  • 打赏
  • 举报
回复
你这能编译的过?!

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧