Alternativa ao if != null

Pessoal,

Pode parecer besteira, mas seguindo as boas práticas, quais seriam as alternativas a códigos como esse:

if(objQQ.getAlgumaCoisa() != null) {
   // código
} else if(objQQ.getOutraCoisa != null) {
   // código
} else if(objQQ.getOutraCoisa2 != null) {
   // código
} else if(objQQ.getOutraCoisa3 != null) {
   // código
} else if(objQQ.getOutraCoisa4 != null) {
   // código
}

Enfim, qual é uma boa alternativa que vocês utilizam pra acabar com um monte de ifs pra verificar se os atributos de um objeto qualquer estão nulos ou não?

Valeu pela ajuda.

usa case, ops case não verifica…

com if é a melhor maneira

É uma boa pergunta. Normalmente você deseja alguma coisa do tipo:

a) Se pelo menos um dos campos não for nulo

ou seja, get1() != null || get2() != null || get3() != null …

b) Se algum dos campos for nulo

ou seja, get1() == null || get2() == null || get3() == null …

c) Se nenhum dos campos for nulo

ou seja, get1() != null && get2() != null && get3() != null …

d) Se o campo for nulo, considerá-lo como vazio

ou seja, em vez de

String campo1 = get1();
if (campo1 == null) 
    campo1 = "";

crie um método que retorne “” se o resultado for null, ou o valor se caso contrário (isso é parecido com o tal do COALESCE do PL/SQL do Oracle)

String campo1 = coalesce (get1());

vc poderia utizar alguma api de validação, como o Hibernate Validator por exemplo

[quote=thingol]É uma boa pergunta. Normalmente você deseja alguma coisa do tipo:

a) Se pelo menos um dos campos não for nulo

ou seja, get1() != null || get2() != null || get3() != null …

b) Se algum dos campos for nulo

ou seja, get1() == null || get2() == null || get3() == null …

c) Se nenhum dos campos for nulo

ou seja, get1() != null && get2() != null && get3() != null …

d) Se o campo for nulo, considerá-lo como vazio

ou seja, em vez de

String campo1 = get1();
if (campo1 == null) 
    campo1 = "";

crie um método que retorne “” se o resultado for null, ou o valor se caso contrário (isso é parecido com o tal do COALESCE do PL/SQL do Oracle)

String campo1 = coalesce (get1());

[/quote]

thingol, a necessidade é basicamente evitar o tenebroso NullPointerException na manipulação deste objeto, ou seja, se o retorno do get1() não for nulo, eu uso ele, senão, passo pra frente. Como nem todos os campos são String, não dá pra retornar “” pra todo mundo, e mesmo usando um método pra retornar “” eu ainda teria que colocar um monte de ifs, o que você acha?

Valeu pela ajuda.

Cria uma classe utilitária

public class ObjectUtils{

    public boolean isNull(Object obj){
        return obj == null;
    }

    public boolean isNotNull(Object obj){
        return obj != null;
    }
    // Outros métodos de verificação
}

Entendi. Hum… não sei se no Java 7 vai dar tempo de implementarem o seguinte:

Normalmente você quer encadear getters, mais ou menos assim:

String sobrenome = sessao.getPessoa ("José").getNomeCompleto().getSobrenome();

Você gostaria que, se algum dos métodos voltasse null, em vez de ficar dando um monte de null pointer exception, você simplesmente obtivesse o valor “null” para sobrenome. Isso acho que até existe para algumas linguagens de script (como o Groovy) mas infelizmente não no Java.

Foi proposto para o Java 7 um operador novo (chamado “elvis” - provavelmente devido à frase “Elvis não morreu” - esse operador vem do Groovy), que ajuda nesse encadeamento. Você poderia fazer então:

String sobrenome = sessao?.getPessoa ("José")?.getNomeCompleto()?.getSobrenome();

que seria equivalente a (só que mais eficientemente):

String sobrenome = sessao != null? sessao.getPessoa ("José") != null ? sessao.getPessoa ("José").getNomeCompleto() != null ? sessao.getPessoa ("José").getNomeCompleto().getSobrenome() : null : null : null;

Por enquanto acho que não dá para fugir muito dos ifs.

Uma das coisas que eu penso é que utilizar valores como “null” é de fato, erros de codificação.

Por exemplo, um NPE será lançado somente em situações onde houve erros de código. Simples assim.

Verificações de nulabilidade é aumentar a possiblidade de se ter problemas, a não ser que você esteja criando um sistema de alta performance e quer ver o GC trabalhando pra caramba.

A minha sugestão é que evite de todas as maneiras que haja valores nulos, na camada de nível mais alto. Por exemplo, sabemos que há situações em que tu não recebe os parâmetros corretos de forms, aí eles virão nulos, mas quando tu tiver que passar algo pra camadas mais baixas (como façade, negócios, persistencia e assim por diante) passe alguma coisa “não-nula”, algo com “estado” ou na melhor das hipóteses, um “enum”.

desculpa se eu não conseguir explicar direito, qualquer coisa eu tento explicar mais tarde denovo ;p

O Tony Hoare (inventor do Quicksort) desculpa-se por ter inventado o null:

http://qconlondon.com/london-2009/speaker/Tony+Hoare

Não dá para aplicar algum pattern não heim?

Criar uma situação tal que poderiamos executar objQQ.getCoisa().execute(); se houver implementação blz caso contrario nada seria executado.

Sera que dá?

flws

[quote=thingol]Entendi. Hum… não sei se no Java 7 vai dar tempo de implementarem o seguinte:

Normalmente você quer encadear getters, mais ou menos assim:

String sobrenome = sessao.getPessoa ("José").getNomeCompleto().getSobrenome();

Você gostaria que, se algum dos métodos voltasse null, em vez de ficar dando um monte de null pointer exception, você simplesmente obtivesse o valor “null” para sobrenome. Isso acho que até existe para algumas linguagens de script (como o Groovy) mas infelizmente não no Java.

Foi proposto para o Java 7 um operador novo (chamado “elvis” - provavelmente devido à frase “Elvis não morreu” - esse operador vem do Groovy), que ajuda nesse encadeamento. Você poderia fazer então:

String sobrenome = sessao?.getPessoa ("José")?.getNomeCompleto()?.getSobrenome();

que seria equivalente a (só que mais eficientemente):

String sobrenome = sessao != null? sessao.getPessoa ("José") != null ? sessao.getPessoa ("José").getNomeCompleto() != null ? sessao.getPessoa ("José").getNomeCompleto().getSobrenome() : null : null : null;

Por enquanto acho que não dá para fugir muito dos ifs.

[/quote]

É exatamente isso thingol, é a idéia de encadear getters mesmo.
Tomara que implementem isso no Java 7, mas por enquanto, é colocar um monte de IFs mesmo.

Valeu cara!

[quote=Leozin]Uma das coisas que eu penso é que utilizar valores como “null” é de fato, erros de codificação.

Por exemplo, um NPE será lançado somente em situações onde houve erros de código. Simples assim.

Verificações de nulabilidade é aumentar a possiblidade de se ter problemas, a não ser que você esteja criando um sistema de alta performance e quer ver o GC trabalhando pra caramba.

A minha sugestão é que evite de todas as maneiras que haja valores nulos, na camada de nível mais alto. Por exemplo, sabemos que há situações em que tu não recebe os parâmetros corretos de forms, aí eles virão nulos, mas quando tu tiver que passar algo pra camadas mais baixas (como façade, negócios, persistencia e assim por diante) passe alguma coisa “não-nula”, algo com “estado” ou na melhor das hipóteses, um “enum”.

desculpa se eu não conseguir explicar direito, qualquer coisa eu tento explicar mais tarde denovo ;p[/quote]

Leozin, o que acontece é que, por boas práticas, todos os métodos públicos devem validar os seus argumentos antes de manipulá-los, bem no esquema do serviço mesmo, você implementa um método pra outra pessoa usar, logo, essa outra pessoa pode te passar algo nulo. Então, para o erro não acontecer no seu método (serviço) você faz essa validação.

Att.

[quote=fantomas]Não dá para aplicar algum pattern não heim?

Criar uma situação tal que poderiamos executar objQQ.getCoisa().execute(); se houver implementação blz caso contrario nada seria executado.

Sera que dá?

flws

[/quote]

Seria bem interessante.

Bom, eu sei que nao é exatamente o que vc esta procurando, mas pelo menos economiza linhas de código…
por exemplo, temos um objeto Pessoa p; e um atributo nome do tipo String…
*EDIT e um campo sobreNome tbem neh
na hora de setar o nome em um campo na tela, ao invés de fazer:

String nomeCompleto = ""; if (p.getNome() != null) { nomeCompleto = p.getNome(); if (p.getSobreNome() != null) { nomeCompleto += " " + p.getSobreNome(); } } jTextField1.setText(nomeCompleto);
eu costumo usar o operador condicional ternário

jTextField1.setText((p.getNome() != null) ? (p.getSobreNome() != null) ? p.getNome() + " " + p.getSobreNome() : p.getNome() : "");

mas mesmo assim, com dois atributos, a linha ja ficou ruim pra ler, mais eu uso bastante isso, nao só com validações de null, mas tbem com objetos booleanos…

[quote=Joao.Gabriel]

Leozin, o que acontece é que, por boas práticas, todos os métodos públicos devem validar os seus argumentos antes de manipulá-los, bem no esquema do serviço mesmo, você implementa um método pra outra pessoa usar, logo, essa outra pessoa pode te passar algo nulo. Então, para o erro não acontecer no seu método (serviço) você faz essa validação.

Att.[/quote]

Concordo que seja ideal validar os parâmetros, mas validar parâmetros nulos eu acho que é um saco hehehe. Validar o estado do objeto tudo bem, mas acho que validar se o mesmo é nulo ou não, era algo que deveria ser evitado ao máximo, como por exemplo, evitando possibilidades de descer o nível de objetos nulos entre as camadas.

Inicializar os campos dos objetos com valores default não evita esse tipo de problema? Tipo:

[code]
public class Pessoa{

 public Pessoa(){
     nome = "";
     idade = 0;
 }

}[/code]