Petit détail, tu sais que tu peux faire un nouveau paragraphe dans un message sans en poster un à chaque fois ?
Pour ta question, c'est une histoire d'allocation.
La seconde construction (String str = "foo") crée un string "foo" interne à tous les Strings : tous les Strings littéraux qui contiennent les mêmes caractères feront référence au même objet par la suite. C'est une optimisation qui permet, entre autre, des comparaisons plus rapides.
Du coup, on a toujours "foo" == "foo".
Quand tu utilises la construction par new String("foo"), tu crées un objet String unique. Par conséquent, "foo" == new String("foo") sera faux.