Q:

Java String Objects

I have the following code: 
public class Porow{
    public static void main (String[] args){
        String s1 = "foo";
        String s2 = "foo";

        System.out.println(s1 == s2);
        System.out.println(s1.equals(s2));

        String s3 = new String ("foo");
        System.out.println(s1 == s3);
        System.out.println(s1.equals(s3));
    }
}

which outputs: 
true
true
false
true

I am trying to understand and explain what's going on here. And I need some guidance. Will I be right to say s1 and s2 are same objects stored in different parts of memory and that's why we get the first 2 trues? 
Why is the 3rd output false? is s3 a different object? and why does it produce true with the equals method on s1? I'd appreciate some help. Thanks :).
EDIT: 
This question is not about == nor equals() I know what they are. My question is more related to memory references and addresses. So don't just presume I'm asking about String Comparison. I'm asking about a whole different thing here. 

A:

That's because in the 3rd scenario, a new object is created(the new keyword creates a new string object) and == is used for object reference equality. That's why it returns false.
Whereas the equals() method is used for String value equality, and hence, it returns true.
In the first and second case, the "foo" String literal is interned and thus, both s1 and s2 refer the same String literal.

