#java
#java
Вопрос:
Просто из любопытства, я написал этот фрагмент кода (я знаю, что это плохой код, я заменил его с тех пор). Это метод toString DocumentTreeNode, который означал, что он рекурсивно вызывался в цикле for (как я уже сказал, плохая идея). Интересно, что он зависал, когда набор дочерних элементов был пуст, кто-нибудь может объяснить, почему это произошло?
Примечание: children
является ли TreeSet в данном случае пустым
public String toString() {
MoreObjects.ToStringHelper helper =
MoreObjects.toStringHelper(getClass())
.add("parent", this.parent)
.add("key", this.key)
.add("value", this.value);
for (DocumentTreeNode<V> child : children.values()) {
helper = helper.add("child", child);
}
return helper.toString();
}
Комментарии:
1. Если он действительно пуст, этого не происходит. Расширенный цикл for немедленно обнаружит, что
children.values().iterator().hasNext()
это false. Я бы ожидал, что на самом деле это непреднамеренный рекурсивный вызов этогоtoString()
метода, т. е. один изthis.parent
,this.key
this.value
равноthis
.2. Расширенный
for
цикл над массивом нулевой длины или пустымIterable
не зависает. Управление просто проходит, при этом выполняется нулевое количество итераций тела цикла.3. На самом деле, я не думаю, что это рекурсивный вызов — который достаточно быстро завершился бы неудачей с
StackOverflowError
.4. Являетесь ли вы дочерним элементом своего собственного родителя? Выполняется ли
helper.add()
вызовtoString()
второго аргумента? Если да для обоих, у вас есть бесконечный цикл рекурсии прямо здесь. Может занять некоторое время, но в конечном итоге вы получитеStackOverflowError
.5. Parent в этом сценарии равен null, случай, который я использовал, имеет только root.
Ответ №1:
Вы добавляете представление parent
в toString
, которое вызывает его toString
. В свою очередь, он вызывает toString
своих дочерних элементов, каждый из которых снова вызывает этот метод для родительского элемента. У вас получается бесконечный цикл.
Upd. Хотя я ожидал бы, что это быстро прекратится с чем-то вроде stackoverflow. Я рекомендую вам запустить это в отладчике и пошагово выполнить код для проверки предложенной гипотезы.