== in essence means same memory location. .equals() means content is equal. If two objects are the same Java stores them in the same place therefore == is true unless one of them has been created programatically . It's worth playing around with to see what happens. Also, == works differently with primitives than it does with objects.
Integer a = 1
Integer b = 1
a == b is true
// makes two different memory locations
Integer a = new Integer(1)
Integer b = new Integer(1)
Strings work a little different, due to the String Pool. Any String that is a compile time constant is put into the pool, and all references point to the same one. You can try this to see == not work (NOT recommended for real code, just for an example):
(I think have that right...
There are only two hard things in computer science: cache invalidation, naming things, and off-by-one errors
The above gives you false on line 6 because the compiler cannot determine that the value of bar is going to be "Foo"; all it knows is that the value will be the concatenation of whatever the variable f and the variable oo happen to be when line 4 is executed. However, if you tell the compiler that the variables will never change, then it can determine the value assigned to bar and will pool the String values. Note that you don't need to declare bar as final in this case to get the Strings pooled.
The best ideas are the crazy ones. If you have a crazy idea and it works, it's really valuable.—Kent Beck