This week's book giveaway is in the General Computing forum. We're giving away four copies of Arduino in Action and have Martin Evans, Joshua Noble, and Jordan Hochenbaum on-line! See this thread for details.
Immutable means that once a String object is created, its content cannot be modified.
Have a look at the methods in class String (look at the API documentation). You'll see that there are no methods that change the content of the String. Note that all methods that do something with the String, such as toLowerCase() and toUpperCase(), return a new String object - they do not modify the original String object.
I don't know if this qualifies for a simple explanation, but I found it helpful to actually see how the bytecode comes out.
So do something simple like:
Than compile it and run javap -c to decompile it to bytecode. If you keep the program REALLY simple, you'll be able to see what's really going on with Strings behind the scenes. You don't have to understand the opcode to a tee (the operation instructions in the bytecode) to be able to see when it's added a string literal to the string pool (Constant Literal Pool) because it will say ldc for load constant, or when it creates a whole new String, etc. I'm sure some may discourage this, but I found it quite helpful. Give it a try, it couldn't hurt!