This question seems to have come up a lot lately. As the code David posted shows, any Integer objects created with a hard-coded literal between -3 and 10 inclusive will use the same object in the string pool. Thus, when you use toString(), you get a true result for those strings.
Don't ask me why they chose to implement it this way, I have no idea.
String objects must be compared with the help of equals() method (compares object state) and not with "==" (compares object identity). "==" does not compare the content of the two Strings instead it compares the addresses of the two Strings. The explanation for this behaviour is that values greater than 10 are built from scratch . ........ case 10: return "10"; ........