2016-08-16 2 views
0

Это мой код:Почему я получаю цикл Infinite (ошибка Stackoverflow) при создании объекта в классе с конструктором?

public class ConstructorsDemo{ 

    public static void main(String a[]){ 

     Cons1 c1 = new Cons1(); 

    } 

} 

class Cons1{ 

    Cons1 c = new Cons1();// the error is in this line 

    Cons1(){ 

     //does somwthing 

    } 
} 

Так я получаю бесконечную ошибку петли здесь (Stackoverflow). Однако это прекрасно, если я прокомментирую любой из двух объектов, которые я создал.

Каким образом объект c в моем коде вызывает ошибку Stackoverflow?

+1

Вы можете выполнить код в своем отладчике, чтобы узнать, почему ваш код является рекурсивным. –

ответ

0

Первый пункт: это бесконечная рекурсия, не бесконечный цикл. Есть большая разница. Есть вполне законные причины использовать бесконечные циклы, и они не будут, в общем, вызывать исключения переполнения стека. Однако есть no законные варианты использования для бесконечной рекурсии, и его использование будет неизменно приведет к исключению переполнения стека. (Полагаю, вы могли бы спорить о бесконечной рекурсии хвоста в нескольких странных ситуациях для языков, которые есть, но все же ...) Если вы получаете исключение переполнения стека, то почти наверняка бесконечная рекурсия, а не бесконечный цикл.

Основная проблема здесь, как указывали другие, заключается в том, что каждый раз, когда вы называете «новым», он, в свою очередь, создает новый объект, который, в свою очередь, создает новый объект и т. Д. И т. Д.

Cons1 c = new Cons1(); 
1
Cons1 c = new Cons1();// 

Пожалуйста, удалите это утверждение и инициализируйте его там, где вы собираетесь его использовать. Код является рекурсивным.

0

вы создаете объект рекурсивно, каждый раз, когда вы создаете объект, поэтому вы получили бесконечный цикл и ведьма вызывает переполнение стека

+1

Бесконечная рекурсия, * не * бесконечный цикл. Бесконечные циклы обычно не вызывают исключения переполнения стека. – EJoshuaS

+0

Рекурсия имеет ту же концепцию цикла, что и повторение вызова, пока не будет выполнено условие возврата.Всякий раз, когда этот метод вызывается, в стеке создается новый блок для хранения локальных примитивных значений и ссылки на другие объекты в методе, и это вызвало переполнение стека – whyn0t

+0

Да, но бесконечный цикл не увеличивает стек, так как, как только вы вернетесь из вызова функции, вы можете снова сжать стек, и любые локальные переменные станут подходящими для сбора мусора (по крайней мере, на управляемом языке, таком как Java или C#). Это не так в коде, который он поставил выше. если вы делаете while (true) {someMethodCall (a, b, c); } стек будет расти, чтобы разместить someMethodCall, а затем сразу же сжиматься снова, как только someMethodCall возвращается, но если вы делаете someMethodCall (a, b, c) {возвращаете someMethodCall (a, b, c); } вы просто будете продолжать наращивать стек на неопределенный срок. – EJoshuaS

2

Давайте посмотрим на ваш класс.

Он имеет (пустой) конструктор и поле того же типа, что и класс.

И это поле инициализируется непосредственно на месте.

Вещь: в Java существует well-defined process, которая определяет, как/когда конструкторы вызываются, и как инициализируются поля класса. И хорошо, поля участников инициализируются как часть вызовов на «новый».

Приводя к: когда в вашем основном классе вызывается «новое», необходимо создать и инициализировать новый объект Cons1. Этот объект Cons1 имеет это поле Cons1. Для чего требуется инициализировать новый объект Cons1 с ... и так далее.

И вот как вы создали свою первую бесконечную рекурсию в Java.

Смежные вопросы