黑马程序员技术交流社区

标题: 对于构造代码块的输出位置的问题 [打印本页]

作者: 郑文博    时间: 2012-6-29 14:13
标题: 对于构造代码块的输出位置的问题
本帖最后由 郑文博 于 2012-6-29 16:10 编辑
  1. /*
  2.         构造代码块练习
  3. */
  4.         
  5. class Person
  6. {
  7.         private String name;
  8.         private int age;
  9.         
  10.         Person()
  11.         {        
  12.         }
  13.         Person(String name)
  14.         {
  15.                 this.name=name;
  16.         }
  17.         /**/
  18.         {
  19.                 System.out.println("person code run");
  20.                 cry();
  21.         }        
  22.         public void speak()
  23.         {
  24.                 System.out.println("name="+name+"..age="+age);
  25.         }
  26.         public void cry()
  27.         {
  28.                 System.out.println("cry.....");
  29.         }
  30. }

  31. class  PersonDemo
  32. {
  33.         public static void main(String[] args)
  34.         {
  35.                 Person p = new Person();
  36.                 Person p1 = new Person("xiaobei");
  37.                 p.speak();
  38.                 p1.speak();
  39.         }
  40. }
复制代码
大家都知道构造代码块在对象一建立就运行,优先于构造函数。它的作用是给所有对象同意初始化。
以上这段程序的输出结果是:
  1. person code run
  2. cry.....
  3. person code run
  4. cry.....
  5. name=null..age=0
  6. name=xiaobei..age=0
复制代码
我的问题是,问是否有方法可以达成输出结果顺序是以下这样呢?
  1. person code run
  2. cry.....
  3. name=null..age=0
  4. person code run
  5. cry.....
  6. name=xiaobei..age=0
复制代码
--------------------------------编辑后分隔----------------------------------
多谢大家回复了,后来我也想到了。主要还是对 “对象一建立就运行”理解不够。
作者: 黄克帅    时间: 2012-6-29 14:41
你把main方法里面调用顺序改一下啊

public static void main(String[] args)
        {

                Person p = new Person();
                p.speak();
                Person p1 = new Person("xiaobei");
                p1.speak();

        }
作者: 乞文超    时间: 2012-6-29 14:49
class  PersonDemo

{

        public static void main(String[] args)
        {

                Person p = new Person();
                                p.speak();
                Person p1 = new Person("xiaobei");
                                p1.speak();

        }

}
作者: 孙浩迪    时间: 2012-6-29 14:55
/*
        构造代码块练习
*/
        
class Person
{
        private String name;
        private int age;
        
        Person()
        {        
        }
        Person(String name)
        {
                this.name=name;
        }
        /**/
       static  {          //这加个static  应该可以,你试一下 。   静态代码块随着类只加载一次。。第二次就不加载了
                System.out.println("person code run");
                cry();
        }        
        public void speak()
        {
                System.out.println("name="+name+"..age="+age);
        }
        public void cry()
        {
                System.out.println("cry.....");
        }
}

class  PersonDemo
{
        public static void main(String[] args)
        {
                Person p = new Person();
                Person p1 = new Person("xiaobei");
                p.speak();
                p1.speak();
        }
}

作者: 游洪波    时间: 2012-6-29 15:19
/*
        构造代码块练习
*/
        
class Person
{
        private String name;
        private int age;
        
        Person()
        {        
        }
        Person(String name)
        {
                this.name=name;
        }
        /**/
        {
                System.out.println("person code run");
                cry();
        }        
        public void speak()
        {
                System.out.println("name="+name+"..age="+age);
        }
        public void cry()
        {
                System.out.println("cry.....");
        }
}

class  PersonDemo
{
        public static void main(String[] args)
        {
                Person p = new Person();
                Person p1 = new Person("xiaobei");
                p.speak();
                p1.speak();
        }
}
上边是你的源代码我给你说下你这段程序的执行过程,首先你用new person()创建了person对象,那么它首先回去找person中无参的构造方法,public person(){}因为你这段代码中没有任何的东西所以什么也没有输出,接下来构造方法执行完成以后,会去执行代码块中的语句,     
{
                System.out.println("person code run");
                cry();
        }      
首先会在控制台打印一句   person code run  打印完成以后会调用     cry();方法
       public void cry()
        {
                System.out.println("cry.....");
        }
执行cry()方法中的语句,所以紧接着又会在控制台打印一句   cry.....  执行完以后你又在下边用
new Person("xiaobei");又创建了一个person对象,但是这次调用的是person中有参数的构造方法。所以执行
    Person(String name)
        {
                this.name=name;
        }
给name属性赋值,赋值完成以后又会去执行代码块中的内容
{
                System.out.println("person code run");
                cry();
        }   
又在控制台打印了一句  person code run  ,打印完以后再次调用 cry();方法
       public void cry()
        {
                System.out.println("cry.....");
        }
又在控制台打印了一句 cry......  这次打印完以后继续回到mian方法中,执行下边的
p.speak();方法
     public void speak()
        {
                System.out.println("name="+name+"..age="+age);
        }
在控制台输出name=name..age=age,这个时候由于你p这个对象创建的时候调用的是无参数的构造方法,所以name值和age值都是默认值,所以你看到控制台输出了name=null..age=0
执行完这个方法以后返回main方法  ,再去继续往下执行
     p1.speak();  同上边一样会输出name=name..age=age但是这次由于你 p1对象创建时调用的是有参数的构造方法,在构造方法中给name赋值了一个xiaobei,所以这个时候你在控制台看到了name=xiaobei..age=0
这个是你上边程序的执行流程,如果你想要按照你上边的预期的方式输出的话,可以吧main方法中的语句交换下位置,也就是交换他们的执行顺序
        public static void main(String[] args)
        {
                Person p = new Person();
                p.speak();
                Person p1 = new Person("xiaobei");
                p1.speak();
        }
这样就和你所预期的结果一样了!

作者: 孙飞    时间: 2012-6-29 15:30
本帖最后由 feigecal 于 2012-6-29 15:32 编辑

构造代码块是对象建立才执行的,你创建一个对象它就运行一次,当然你不创建对象它就 不执行了,所以你只用在main方法里在创建了第一个对象后就让对象调用speak方法,因为代码执行顺序是从上到下的,等执行过了p对spead方法的调用你再让它创建对象p1,它就再哭一次,然后再执行自己对应的构造函数赋值,然后p1再调用speak方法呗,只是顺序问题
作者: 郑文博    时间: 2012-6-29 16:12
sunhaodi 发表于 2012-6-29 14:55
/*
        构造代码块练习
*/

有点意思,你说说这是为什么呢?
作者: 郑文博    时间: 2012-6-29 16:13
sunhaodi 发表于 2012-6-29 14:55
/*
        构造代码块练习
*/

有点意思,你说说这是为什么呢?
作者: 孙浩迪    时间: 2012-6-29 16:19
郑文博 发表于 2012-6-29 16:13
有点意思,你说说这是为什么呢?

这叫静态代码块啊, 老毕视频讲的很清楚的,   这个静态代码块最先执行,而且随着类加载,但只加载一次,你在创建它也不会加载了。。 一般也是用于初始化用的
作者: 郑文博    时间: 2012-6-29 21:15
sunhaodi 发表于 2012-6-29 16:19
这叫静态代码块啊, 老毕视频讲的很清楚的,   这个静态代码块最先执行,而且随着类加载,但只加载一次, ...

我是说 有没有考虑为什么会只加载一次呢?
作者: 孙浩迪    时间: 2012-6-29 21:20
郑文博 发表于 2012-6-29 21:15
我是说 有没有考虑为什么会只加载一次呢?

那就得说到堆和栈的问题了, 静态的是在堆内存,   可能就加载一次吧, 具体我也不太清楚啊,我上网查一下吧
作者: 郑文博    时间: 2012-6-29 21:34
sunhaodi 发表于 2012-6-29 21:20
那就得说到堆和栈的问题了, 静态的是在堆内存,   可能就加载一次吧, 具体我也不太清楚啊,我上网查一 ...

静态的都属于类啊  都是随着类的加载加载一次啊  
类只有一份,所以只加载一次
:P




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