Em Java me disseram que, ao fazer uma verificação nula, deve-se usar == em vez de .equals (). Quais são as razões para isso?
Em Java me disseram que, ao fazer uma verificação nula, deve-se usar == em vez de .equals (). Quais são as razões para isso?
Respostas:
São duas coisas completamente diferentes. ==
compara a referência do objeto, se houver, contida por uma variável. .equals()
verifica se dois objetos são iguais, de acordo com o contrato, para o que significa igualdade. É perfeitamente possível que duas instâncias de objetos distintas sejam "iguais" de acordo com o contrato. E há os pequenos detalhes de que, como equals
é um método, se você tentar invocá-lo em uma null
referência, receberá um NullPointerException
.
Por exemplo:
class Foo {
private int data;
Foo(int d) {
this.data = d;
}
@Override
public boolean equals(Object other) {
if (other == null || other.getClass() != this.getClass()) {
return false;
}
return ((Foo)other).data == this.data;
}
/* In a real class, you'd override `hashCode` here as well */
}
Foo f1 = new Foo(5);
Foo f2 = new Foo(5);
System.out.println(f1 == f2);
// outputs false, they're distinct object instances
System.out.println(f1.equals(f2));
// outputs true, they're "equal" according to their definition
Foo f3 = null;
System.out.println(f3 == null);
// outputs true, `f3` doesn't have any object reference assigned to it
System.out.println(f3.equals(null));
// Throws a NullPointerException, you can't dereference `f3`, it doesn't refer to anything
System.out.println(f1.equals(f3));
// Outputs false, since `f1` is a valid instance but `f3` is null,
// so one of the first checks inside the `Foo#equals` method will
// disallow the equality because it sees that `other` == null
public int data
?
Object
, sim. Ele é substituído por um grande número de classes JDK. Mas o ponto não é sobre implementação, é sobre semântica. (Nota: o JDK7 está muito desatualizado.)
Se você invocar .equals()
em null
você obteráNullPointerException
Portanto, é sempre aconselhável verificar a nulidade antes de chamar o método, sempre que aplicável
if(str!=null && str.equals("hi")){
//str contains hi
}
Veja também
if ("hi".equals(str))
.
someObject.equals(null)
aumentará a NullPointerException
sem nunca inserir o método equals.
Objects.equals(a, b)
Ele não vai aumentar NullPointerException, mas ainda depende do método de "igual" do "a" e "b"
Além da resposta aceita ( https://stackoverflow.com/a/4501084/6276704 ):
Desde o Java 1.7, se você deseja comparar dois objetos que podem ser nulos, recomendo esta função:
Objects.equals(onePossibleNull, twoPossibleNull)
java.util.Objects
Esta classe consiste em métodos utilitários estáticos para operar em objetos. Esses utilitários incluem métodos nulos, seguros ou tolerantes a nulos, para calcular o código hash de um objeto, retornar uma sequência para um objeto e comparar dois objetos.
Desde: 1.7
No Java 0 ou nulo, são tipos simples e não objetos.
O método equals () não é criado para tipos simples. Tipos simples podem ser combinados com ==.
foo.equals(null)
O que acontece se foo for nulo?
Você recebe uma NullPointerException.
De acordo com fontes , não importa o que usar para a implementação do método padrão:
public boolean equals(Object object) {
return this == object;
}
Mas você não pode ter certeza equals
na classe personalizada.
equals
só pode retornar false
ou causar um NullPointerException
(ou algo diferente se o equals
método substituído não for bom).
Object.equals é nulo seguro, no entanto, esteja ciente de que, se dois objetos forem nulos, object.equals retornará true, portanto, verifique se os objetos que você está comparando não são nulos (ou mantêm valores nulos) antes de usar object.equals para comparação.
String firstname = null;
String lastname = null;
if(Objects.equals(firstname, lastname)){
System.out.println("equal!");
} else {
System.out.println("not equal!");
}
O exemplo de snippet acima retornará igual!
Como equal é uma função derivada da classe Object, essa função compara itens da classe. se você usá-lo com nulo, ele retornará falso, porque o conteúdo da classe não é nulo. Além disso, == compara a referência a um objeto.
false
ou NullPointerException
(se equals
não for substituído por algo ruim).
Aqui está um exemplo em que, str != null
mas str.equals(null)
ao usarorg.json
JSONObject jsonObj = new JSONObject("{field :null}");
Object field = jsonObj.get("field");
System.out.println(field != null); // => true
System.out.println( field.equals(null)); //=> true
System.out.println( field.getClass()); // => org.json.JSONObject$Null
EDIT:
aqui está a classe org.json.JSONObject $ Null :
/**
* JSONObject.NULL is equivalent to the value that JavaScript calls null,
* whilst Java's null is equivalent to the value that JavaScript calls
* undefined.
*/
private static final class Null {
/**
* A Null object is equal to the null value and to itself.
*
* @param object
* An object to test for nullness.
* @return true if the object parameter is the JSONObject.NULL object or
* null.
*/
@Override
public boolean equals(Object object) {
return object == null || object == this;
}
}
field.equals(null)
retorna verdadeiro. Isso interrompe o comportamento comum do Java e, portanto, é confuso. Deve funcionar apenas field.equals("null")
, pelo menos no meu ponto de vista. Não sei por que os desenvolvedores da biblioteca pensaram que isso seria bom para dar suporte.
str != null
e str.equals(null)
retornar true
ao usar o org.json ."?
jsonObject
contém a chave "campo" é por isso que field
não é nulo, ele tem uma referência que contém o json.org.JSONObject$Null
objeto
Null
como null
e usaria em seu "null"
lugar. Mas acho que eles fizeram isso para evitar exigir Strings. Mas mesmo com essa lib, field.equals(null)
ainda é quase sempre um problema: P.
Seu código infringe a lei de Deméter. É por isso que é melhor refatorar o design em si. Como solução alternativa, você pode usar o Opcional
obj = Optional.ofNullable(object1)
.map(o -> o.getIdObject11())
.map(o -> o.getIdObject111())
.map(o -> o.getDescription())
.orElse("")
acima é verificar a hierarquia de um objeto, basta usar
Optional.ofNullable(object1)
se você tiver apenas um objeto para verificar
Espero que isto ajude !!!!
Você sempre pode fazer
if (str == null || str.equals(null))
Isso primeiro verificará a referência do objeto e depois o próprio objeto, fornecendo que a referência não seja nula.
x.equals(null)
.
equals()
e ver. Quando você tenta será imediatamente óbvia