"" é uma string real, embora vazia.
null, no entanto, significa que a variável String não aponta para nada.
a==b
retorna false porque "" e null não ocupam o mesmo espaço na memória - em outras palavras, suas variáveis não apontam para os mesmos objetos.
a.equals(b)
retorna false porque "" não é igual a nulo, obviamente.
A diferença é que, como "" é uma string real, você ainda pode chamar métodos ou funções nela, como
a.length()
a.substring(0, 1)
e assim por diante.
Se a String for igual a nulo, como b, o Java lançaria a NullPointerException
se você tentar invocar, diga:
b.length()
Se a diferença que você está pensando é = = versus igual, é esta:
== compara referências, como se eu fosse
String a = new String("");
String b = new String("");
System.out.println(a==b);
Isso resultaria falso porque aloquei dois objetos diferentes, e a e b apontam para objetos diferentes.
No entanto, a.equals(b)
nesse caso, retornaria true, porque equals
for Strings retornará true se e somente se o argumento String não for nulo e representar a mesma sequência de caracteres.
Esteja avisado, porém, que o Java tem um caso especial para Strings.
String a = "abc";
String b = "abc";
System.out.println(a==b);
Você pensaria que a saída seria false
, uma vez que deveria alocar duas Strings diferentes. Na verdade, Java internará Strings literais (aquelas que são inicializadas como aeb no nosso exemplo). Portanto, tenha cuidado, pois isso pode dar alguns falsos positivos sobre como == funciona.
b.equals(a)
- mas não use==
para comparação de strings como "não funcionará" de outras maneiras. Onull
valor (que é diferente de uma string vazia""
, uma instância String válida) nunca pode ter um método invocado nela. Colocar o "não nulo conhecido" (geralmente um valor constante ou literal) no lado esquerdo da igualdade é "condicionais Yoda" ou algo parecido.