Page 2 of 2
Remember, use == to check whether two references refer to the same object. Use equals() to check whether the contents of two objects are equal. Do not assume that == will always work for testing strings!
As for Question 3, in the case of d = "hello", d points to the same reference as that pointed to by both a and b. Before the JVM creates a string literal, the JVM checks the string literal pool first. Since "hello" already exists in that pool, d will simply be set to point to that pooled instance.
All three questions are related because the JVM performs some trickery while instantiating string literals to increase performance and decrease memory overhead. The JVM can reuse and share string references because strings are immutable and, therefore, by definition thread-safe. That's a nice design; although a design you must be aware of and treat accordingly.