Functions and variables are stored on stack while string and object references are stored on heap. Why is there a difference on how they are stored?
Some of the comments above offer links to the difference. The stack is temporary. Chunks of the stack are used as your code nests. Think of a big chunk of memory in which you keep track only of the very top of the memory. When you call a method, the system knows how much memory is required to remember where to return to when the method exits and enough space for the variables required for the method. The stack pointer then points higher up in memory, giving you all the space it just skipped over. When your method returns, the stack pointer is returned to where it was before your method was called. Any variables that were there are now gone.
It's not entirely that simple in a complex world like Java, but I still think of the stack in assembly language, which is where I first encountered it. (I'm old.) Close enough for this discussion.
The heap is different. The heap is managed memory with complex structures that keep track of the memory you've used. If you say new Foo(), Java knows how big a Foo is and it asks the heap for enough space to hold one. Much more complex things happen around managing that. But when your method returns, that object still exists. If it were allocated on the stack, there'd be real problems, because the stack unwinds when your method returns. But your memory in the heap is still allocated, and your object can continue to exist.
Again, it's not that simple, but maybe it makes sense.
Space on the stack exists only as long as your method is running. (I presume if you nest inside {}, it might allocate more space. I don't know.) Space on the heap persists until objects are freed, but that can be far longer than the duration of a method call.