I didn't think you could overload operators like that, as you would do in other languages such as c++?
Java doesn't feature operator overloading.
The only effective operator overloading is the built in support for string concatenation using the + sign.
Doesn't == just compare the memory address of two objects to see if its the same? So it'd only return true if the references were the same?
That is correct.
With the existence of the String object pool however and many people first encountering the operator applied to objects (rather than primitives) when trying to compare Strings they often get confused into thinking it does work to compare the content of objects.
Even with Strings though it can in fact fail, depending on how the Strings were constructed.
will yield true because "Hello World" will be placed on the String object pool and the JVM will assign s2 to the same actual instance as s1.
String s1 = "Hello World";
String s2 = new String("Hello World");
boolean b = s1 == s2;
will yield false because here you have forced the JVM to create a new String instance on the heap when defining s2 (containing a clone of the content of s1), thus s1 and s2 don't point to the same instance on the String object pool.
And those are simple examples. In real programs it can get a lot more tricky to figure it out, as the 2 Strings might for example come from deserialised objects received from other programs, previous program runs that stored them on disk, or reflection based generation, performed by classes far removed from your comparison to which you may not have the source.