在我們寫程序的時候經常會用到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
]