java.lang.StackOverflowError
在这里是栈溢出,假如使用栈的时候引用大于栈的内存,则会报此类错误。
在这里我们想要输出本类对象的地址,并且重写了toString()方法。
public class NewTest {
public String toString(){
return "NewTest:"+this+"\n";
}
public static void main(String[] args) {
NewTest nt=new NewTest();
System.out.println(nt);
}
}
运行结果:
Exception in thread "main" java.lang.StackOverflowError
at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:449)
at java.lang.StringBuilder.append(StringBuilder.java:136)
at TheTestOne.NewTest.toString(NewTest.java:5)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at TheTestOne.NewTest.toString(NewTest.java:5)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
这里在添加this的时候会一直重复调用this.toString()方法。那么重复调用的时候为什么会显示栈溢出呢。
在JAVA中关于String的"+"和"+="是被重载过的两个操作符,每次会创建一个StringBuilder对象,在toString()方法压栈执行的时候,会一直调用此方法,并不断地创建StringBuilder对象,就会发生栈溢出(java.lang.StackOverflowError)。
可以这样修改。
public class InfiniteRecursion {
public String toString() {
return "InfiniteRecursion address:" + super.toString() + "\n";
}
public static void main(String[] args) {
InfiniteRecursion ir = new InfiniteRecursion();
System.out.println(ir);
}
}
可以调用父类的oString()方法。这样一来就可以跳出死循环了。
输出结果:
InfiniteRecursion address:m7d9.InfiniteRecursion@152b6651
由此可见,栈内存溢出的一个原因就是栈内的引用太多,从而引发栈溢出。
这里使用了三行"+"符号,第二行中加了两次,但是也只是创建了三个StringBuilder对象,也不是每一次调用"+"符号就会创建一个新的StringBuilder,要视情况而定。
public static void main(String [] args){
String s1="hello";
String s2=s1+"world"+"s2";
String s3=s2+"again";
String s4=s3+"s4";
}
这里是反编译成了汇编语言。可以从左边看到有三个新的StringBuilder对象。
参考书籍:《Thinking in Java》