黑马程序员技术交流社区

标题: 哪个大神能帮忙解释一下这两种的顺序流程 [打印本页]

作者: 青衫禅客    时间: 2014-12-25 22:52
标题: 哪个大神能帮忙解释一下这两种的顺序流程
本帖最后由 青衫禅客 于 2014-12-26 01:06 编辑

如题……

QQ截图20141226010540.png (132.02 KB, 下载次数: 13)

QQ截图20141226010540.png

作者: qowoeo7538    时间: 2014-12-25 23:13
输出的是什么,完全看不清……
作者: 吴海松    时间: 2014-12-26 00:45
你放那两个地方结果都是一样的,都是在成员位置那里,也就是你放的两个位置都是成员变量,
作者: 青衫禅客    时间: 2014-12-26 01:07
qowoeo7538 发表于 2014-12-25 23:13
输出的是什么,完全看不清……

我重新发了一下图,请帮忙看看
作者: 青衫禅客    时间: 2014-12-26 01:08
吴海松 发表于 2014-12-26 00:45
你放那两个地方结果都是一样的,都是在成员位置那里,也就是你放的两个位置都是成员变量, ...

我重新发了一下图,请帮忙看看,就是两个地方结果不一样,我才问发论坛问大家的
作者: 吴海松    时间: 2014-12-26 11:31
你符值都不一样肯定是不一样啊,第一个赋值时38结果是38,第二个赋值是10结果是10,这是正常的啊,
作者: duluhua    时间: 2014-12-26 14:06
我运行试了,int i 放到构造代码块的上下,打印的值是不一样的,想不明白为什么,坐等大神。
作者: 青衫禅客    时间: 2014-12-26 22:12
吴海松 发表于 2014-12-26 11:31
你符值都不一样肯定是不一样啊,第一个赋值时38结果是38,第二个赋值是10结果是10,这是正常的啊, ...

能详细解释一下吗?
作者: 李票    时间: 2014-12-26 23:32
本帖最后由 李票 于 2014-12-26 23:35 编辑

因为构造代码块要比对象优先先要执行,而且代码都是是从上往下执行的,当 i =10在上面时,在构造代码块中i=38将i=10覆盖,打印的都是38。当i=10在下面时,先执行代码块,代码块中的代码执行完后打印后,又将i=10将i=38覆盖了,new过对象调用后打印的是i=10。我说下代码的执行顺序,静态代码快最先执行并且只执行一次,在执行构造代码块,其次是执行构造方法,然后是对象中的函数
作者: 李票    时间: 2014-12-26 23:34
李票 发表于 2014-12-26 23:32
因为构造代码块要比对象优先先要执行,而且代码都是是从上往下执行的,当 i =10在上面时,在构造代码块中i= ...

说反了。i=10在下面时是将i=38覆盖了:)
作者: 赵涛涛    时间: 2014-12-26 23:37
以下是我个人的理解:
1、i在代码块的前面时,
        当你进行A x=new A()创建对象后,因为是执行的默认的构造方法(默认的不显示),执行完构造方法后,就是按顺序执行流程了,所亿,
        i=20;
        1=38
        this.i=38;
        wahaha
        当这些执行完毕后,开始执行你main中new后面的语句println(x.i)

        这个你看有什么问题吗?如果有不同见解,欢迎指教!

2、i在代码块后面时
        抱歉,这个我也不是太懂,不过记得类中的执行顺序是,
        静态代码块----构造代码块——构造方法,
        看有没有大神解答了

       
作者: 青衫禅客    时间: 2014-12-27 00:30
赵涛涛 发表于 2014-12-26 23:37
以下是我个人的理解:
1、i在代码块的前面时,
        当你进行A x=new A()创建对象后,因为是执行的默认的构造方 ...

我的老师说的是先默认初始化,然后从上到下显示初始化,在过程中有构造代码块就执行,没有就算了,最后执行构造函数,但关键当我构造代码块中有一个this.i的时候又是怎么个情况,我老师也还没给我回复呢?
作者: 青衫禅客    时间: 2014-12-27 00:32
李票 发表于 2014-12-26 23:32
因为构造代码块要比对象优先先要执行,而且代码都是是从上往下执行的,当 i =10在上面时,在构造代码块中i= ...

我的老师说的是先默认初始化,然后从上到下进行显示初始化,在这过程中有构造代码块就执行,没有就算了,最后执行构造函数,但关键当我构造代码块中有一个this.i的时候又是怎么个情况,注意有this的情况和没有this的情况不一样的哦,当int i在下面的时候,没有this会编译报错

作者: 赵涛涛    时间: 2014-12-27 22:11
青衫禅客 发表于 2014-12-27 00:32
我的老师说的是先默认初始化,然后从上到下进行显示初始化,在这过程中有构造代码块就执行,没有就算了, ...

老师回复你后,希望把答案贴上来,我也想看看,谢谢啦
作者: zmhlnrs    时间: 2014-12-28 17:26
因为类刚加载进内存的时候成员变量有个默认初始化值  那个i=0;就是成员变量还没有运行完  然后会从上到下一行一行的去执行代码,如果没有没this.的时候 运行到i=38时  成员变量i还没有完全创建成功   当调用i的时候会报错。
有this.的时候会到构造代码块外面去找 。这个时候找到的i=0,所以先把38赋值给i,读到下面的时候又把10赋值给i
所以后面的运行结果是10。
第一种情况很好解释了 就是一行一行的读代码。
作者: Alexrl    时间: 2014-12-28 17:42
是不是先把类的成员加载完了再执行  加载和执行顺序的原因。
作者: 青衫禅客    时间: 2014-12-28 22:47
zmhlnrs 发表于 2014-12-28 17:26
因为类刚加载进内存的时候成员变量有个默认初始化值  那个i=0;就是成员变量还没有运行完  然后会从上到下 ...

当没有this的时候,运行到i=38时,成员变量是已经成功默认初始化的啊,那么就应该可以调用吧?!
作者: yninggis    时间: 2014-12-29 00:41
我试了下,确实像楼主说的那样:一般赋值语句和构造代码块的顺序改变了,结果会有变化。我觉得现在的问题是一般的赋值语句和构造代码块的执行顺序是否固定?还是按照从上到下的顺序执行?我也想知道这个答案!
作者: 雪落纷飞    时间: 2014-12-29 03:11
和构造函数中的this()super()一个道理放在首行,因为初始化的动作要先执行这样才会避免覆盖同名值, 构造代码块和静态代码块都是做初始化动作的所以前面的会被覆盖,
作者: 简体字    时间: 2014-12-29 05:55
都是黑马币啊
作者: 简体字    时间: 2014-12-29 05:56

都是黑马币啊
作者: 简体字    时间: 2014-12-29 05:58

都是黑马币啊
作者: 简体字    时间: 2014-12-29 06:13

都是黑马币啊
作者: 简体字    时间: 2014-12-29 06:15

都是黑马币啊
作者: 青衫禅客    时间: 2014-12-29 12:46
雪落纷飞 发表于 2014-12-29 03:11
和构造函数中的this()super()一个道理放在首行,因为初始化的动作要先执行这样才会避免覆盖同名值, 构 ...

拜托看清楚图中要表明的问题再回帖好不好
作者: 雪落纷飞    时间: 2014-12-29 15:43
本帖最后由 雪落纷飞 于 2014-12-29 16:23 编辑

= =  
当类被加载进内存没调用构造函数new对象之前时候是先在方法区加载A类的信息,(静态成员加载完之后就是非静态信息)一个类里的非静态成员/代码块,按写代码的顺序加载。但调用属性时,必须注意加载顺序。如果在加载前调用,值为默认初始值(如:null 或者 0)。
  当你的i在上面的时候i已加载完成,执行到代码块的时候赋了新值。
  当你的i在下面的时候,还没有加载i调用的只是初始值0的i,(你可以把i=38移到调用i下面一行看看),然后代码块执行继续向下执行到了 int i 才是加载了i的信息并且赋给了一个值。

   楼主要是还看不懂就当我水贴吧。。。。
   

作者: 安卓小蜗牛    时间: 2014-12-29 19:12
{}叫作构造代码块,给所有对象进行初始化,放在里面的代码一般先执行,作用全局的
作者: Android周    时间: 2014-12-30 23:07
,完全看不清……
作者: bird_not_fat    时间: 2014-12-31 11:41
对于第二个问题:
类变量赋值 --》 静态代码快执行 --》成员变量或者非静态代码块执行,按从上到下的先后顺序执行--》构造方法

public class Test3 {
       
//        int i = 1;
        {
                i = 2;
        }
        int i = 1;
        public static void main(String[] args) {
                Test3 t3 = new Test3();
            System.out.println(t3.i);
        }
}
作者: 王景阳    时间: 2014-12-31 13:53
你先写一下  static   int  变量名  让变量和类一起加入进内存  然后在去除static   直接用类加入内存  对比两次显示结果  看是不是有所不同




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2