You get a StackOverflowError whenever the stack gets too "deep". Every time a method is called that adds an entry to the stack, which is removed when that method returns. There's a limited amount of memory allocated to this stack, so if you nest method calls too deep then this can happen.
In practice, this limit is pretty large (hundreds or thousands of calls, depending on the memory allocated). You could reach the limit non-recursively if you really wanted to and had a lot of patience. But in practice some form of recursive loop will nearly always be the cause.