在我们写程序的时候经常会用到toString()的方法,但是这种方法有时候会造成无意识的递归。下面看代码:
import java.util.ArrayList;
import java.util.List;
/**
* Created by msc on 2017/1/8.
*/
public class InfiniteRecursion {
@Override
public String toString() {
return "InfiniteRecursion address: "+this+"\n";
}
public static void main(String[] args) {
List<InfiniteRecursion> v=new ArrayList<InfiniteRecursion>();
for (int i=0;i<10;i++){
v.add(new InfiniteRecursion());
}
System.out.println(v);
}
}
删除代码的toString()方法是打印InfiniteRecursion类的对象的内存地址。
我们都知道在这里this就是代表了当前对象,当this关键字和字符串连接的时候,也会转换成该对象的地址,会调用toString()方法,而这个this原本就在toString()方法中,会造成什么后果呢?就是永远地在递归调用,直到堆栈溢出。下面看运行上述代码所报的异常。
Exception in thread "main" java.lang.StackOverflowError
at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:121)
……
那么我们想要查看InfiniteRecursion类的地址应该怎么做呢?可以通过调用其父类的toString()方法来实现,虽然InfiniteRecursion这个类没有明确的继承某个类,但是我们知道所有的类都是默认继承Object类的。
import java.util.ArrayList;
import java.util.List;
/**
* Created by msc on 2017/1/8.
*/
public class InfiniteRecursion {
@Override
public String toString() {
return "InfiniteRecursion address: "+super.toString()+"\n";
}
public static void main(String[] args) {
List<InfiniteRecursion> v=new ArrayList<InfiniteRecursion>();
for (int i=0;i<10;i++){
v.add(new InfiniteRecursion());
}
System.out.println(v);
}
}
看运行结果:
[InfiniteRecursion address: InfiniteRecursion@4554617c
, InfiniteRecursion address: InfiniteRecursion@74a14482
, InfiniteRecursion address: InfiniteRecursion@1540e19d
, InfiniteRecursion address: InfiniteRecursion@677327b6
, InfiniteRecursion address: InfiniteRecursion@14ae5a5
, InfiniteRecursion address: InfiniteRecursion@7f31245a
, InfiniteRecursion address: InfiniteRecursion@6d6f6e28
, InfiniteRecursion address: InfiniteRecursion@135fbaa4
, InfiniteRecursion address: InfiniteRecursion@45ee12a7
, InfiniteRecursion address: InfiniteRecursion@330bedb4
]