A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 丁朋伟 黑马帝   /  2011-9-21 08:34  /  4003 人查看  /  6 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

挺郁闷的错,高手指点下
public class Person {

      Person person ;
       
          public static void main(String[] args){
                  Person a = new Person();
      }
          
          {
                  person = new Person ();
          }
          
          public Person(){
                  System.out.println(person);
          }
}
报错:Exception in thread "main" java.lang.StackOverflowError

6 个回复

倒序浏览
黑马网友  发表于 2011-9-21 08:38:11
沙发
你的程序貌似有问题,再说你想写什么样的程序,怎么写成这样了,自己把自己搞了....

建议对java不太熟悉的话,就不要写这种没人写的程序来考研自己对java的理解程序,这样没多大意义,实际中谁也不会设计这样的程序。。。。
回复 使用道具 举报
黑马网友  发表于 2011-9-21 08:47:57
藤椅
小生在学习构造器初始化,出了点小问题,如果您解决不了,又耽误了您的时间我深感歉意
回复 使用道具 举报
黑马网友  发表于 2011-9-21 08:58:31
板凳
package test;
public class Person {

      Person person;
        
          public static void main(String[] args){
                  Person a = new Person();
      }
           
          {
                  [color=Red]person = new Person (); //代码2[/color]          }
           
         [color=Red] public Person(){ //代码1
                  System.out.println(person);
          } [/color]}
你的程序首先执行代码1然后执行代码2,然后就一直循环执行代码1和代码2,是一个死循环,因为person类的构造方法执行的时候要先去执行代码块,然后执行构造函数,而代码块中有调用了构造方法,这样就死锁了,希望能帮你。

评分

参与人数 1技术分 +1 收起 理由
admin + 1

查看全部评分

回复 使用道具 举报
黑马网友  发表于 2011-9-21 09:31:26
报纸
public class Person {
         Person person;
        public static void main(String[] args) {
                Person a = new Person();
        }
        {
                System.out.println("aaaa");
                person = new Person();
        }

        public Person() {
                System.out.println(person);
        }
}
在程序块里打印一句话
输入:
aaaa
aaaa
aaaa
aaaa
aaaa
aaaa
aaaa
aaaaException in thread "main" java.lang.StackOverflowError
        at sun.nio.cs.ext.DoubleByteEncoder.encodeArrayLoop(DoubleByteEncoder.java:126)
        at sun.nio.cs.ext.DoubleByteEncoder.encodeLoop(DoubleByteEncoder.java:189)
        at java.nio.charset.CharsetEncoder.encode(CharsetEncoder.java:544)
        at sun.nio.cs.StreamEncoder.implWrite(StreamEncoder.java:252)
        at sun.nio.cs.StreamEncoder.write(StreamEncoder.java:106)
        at java.io.OutputStreamWriter.write(OutputStreamWriter.java:190)
        at java.io.BufferedWriter.flushBuffer(BufferedWriter.java:111)
        at java.io.PrintStream.newLine(PrintStream.java:495)
        at java.io.PrintStream.println(PrintStream.java:757)
        at Test.Person.<init>(Person.java:12)

说明先执行的是代码块的代码,再调用构造方法

假如这样改动代码
public class Person {
        static Person person = null;
        public static void main(String[] args) {
                Person a = new Person();
        }
        static{
                System.out.println("aaaa");
                 person = new Person();
        }
        public Person() {
                System.out.println(person);
        }
}
输出结果:
aaaa
null
Test.Person@de6ced
为什么会出先空值呢?
回复 使用道具 举报
黑马网友  发表于 2011-9-21 10:09:10
地板
是这样的

首先,你要明白的是,如果java.lang.StackOverflowError这个错误出现的话
它通常表示的是:你的内存已经被填满了,放不下更多的对象了
而内存为什么会被填满呢?那就是宋红旺童鞋的答案:
你的程序中产生了死循环,从而导致在内存中无限创建Person对象,最后使内存被填满并报错

===============================================

好,既然我们知道了报错的原因是程序中产生了死循环
那么我们就来看看为什么会产生死循环

首先,为了方便下一步的理解
我们可以根据楼上杨华童鞋测试的前半部分,得出两个结论:
1、程序首先会执行{}代码块的代码,然后才调用构造方法
2、每次创建一个Person对象的时候,{}代码块中的语句都要执行一次
[color=Red]*至于这两个结论是如何得出的,你就自己思考下吧呵呵[/color]

===============================================

好,了解上面两个结论以后,我们再来看看是哪里产生了死循环吧:

首先,根据上面的结论1:程序首先会执行{}代码块的代码,然后才调用构造方法
所以,当你第一次创建Person对象的时候
程序就会首先执行{}代码块中的代码
这时就会创建一个新的Person对象

然后,根据上面的结论2:每次创建一个Person对象的时候,{}代码块中的语句都要执行一次
所以,当程序在创建新的Person对象的时候,就又会先执行{}代码块中的代码
所以这时就又会创建一个新的Person对象

然后,根据上面的结论2:每次创建一个Person对象的时候,{}代码块中的语句都要执行一次
所以,当程序在创建新的Person对象的时候,就又会先执行{}代码块中的代码
所以这时就又会创建一个新的Person对象

……………………
这样很明显能看出来我的说法是循环了吧

===============================================

然后再回答一下杨华童鞋的问题吧~
其实,你的这个问题就是一个语句的执行顺序问题
与static代码块没有太大关系

当你在调用person = new Person();这行代码的时候
实际上这行代码的执行顺序是这样的:
1、首先调用new Person();构造方法,由于此时前面的"person ="还没有被执行,因此打印出来的是null
2、然后才会执行前面的"person =",将第1步中创建出的Person对象赋值给person

评分

参与人数 1技术分 +2 收起 理由
admin + 2

查看全部评分

回复 使用道具 举报
黑马网友  发表于 2011-9-21 11:08:44
7#
欧拉
明白了
感谢各位大虾的热心解答

评分

参与人数 1技术分 +1 收起 理由
admin + 1

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马