Eu consideraria a questão do ponto de vista da semântica, ou seja, perguntar-me o que representa um ponteiro NULL ou um argumento de referência nula.
Se uma função ou método foo () tiver um argumento x do tipo T, x pode ser obrigatório ou opcional .
Em C ++, você pode passar um argumento obrigatório como
- Um valor, por exemplo void foo (T x)
- Uma referência, por ex. void foo (T & x).
Em ambos os casos, você não tem o problema de verificar um ponteiro NULL. Portanto, em muitos casos, você não precisa de uma verificação de ponteiro nulo em todos os argumentos obrigatórios.
Se você está passando um argumento opcional , você pode usar um ponteiro e usar o valor NULL para indicar que nenhum valor foi dado:
void foo(T* x)
Uma alternativa é usar um ponteiro inteligente como
void foo(shared_ptr<T> x)
Neste caso, você provavelmente desejará verificar o ponteiro no código, porque faz diferença para o método foo () se x contém um valor ou nenhum valor.
O terceiro e último caso é que você usa um ponteiro para uma obrigatória
argumento. Neste caso, chamar foo (x) com x == NULL é um erro e
você tem que decidir como lidar com isso (o mesmo que com um
índice fora dos limites ou qualquer entrada inválida):
- Sem verificação: se houver um bug, deixe-o travar e espere que esse bug apareça cedo o suficiente (durante o teste). Se isso não acontecer (se você falhar em falhar o suficiente), espere que ele não apareça em um sistema de produção porque a experiência do usuário é que eles vêem a falha do aplicativo.
- Verifique todos os argumentos no início do método e relate argumentos NULL inválidos, por exemplo, lance uma exceção de foo () e deixe algum outro método lidar com isso. Provavelmente, a melhor coisa a fazer é mostrar ao usuário uma janela de diálogo dizendo que o aplicativo encontrou um erro interno e será fechado.
Além de uma maneira mais agradável de falhar (dando ao usuário mais informações), uma vantagem da segunda abordagem é que é mais provável que o bug seja encontrado: o programa falhará toda vez que o método for chamado com o erro argumentos, enquanto que com a abordagem 1, o erro só aparecerá se uma declaração que desreferencia o ponteiro for executada (por exemplo, se a ramificação direita de uma instrução if for inserida). Então, a abordagem 2 oferece uma forma mais strong de "falhar cedo".
Em Java você tem menos opções porque todos os objetos são passados usando referências que sempre podem ser nulas. Novamente, se o valor null representar um valor NONE de um argumento opcional, a verificação do valor nulo provavelmente fará parte da lógica de implementação.
Se o nulo é uma entrada inválida, então você tem um erro e eu aplicaria considerações semelhantes como no caso dos ponteiros C ++.
Como em Java você pode pegar exceções de ponteiro nulo, a abordagem 1 acima é equivalente a abordagem 2 se o método foo () desreferenciar todos os argumentos de entrada em todos os caminhos de execução (o que provavelmente ocorre com muita freqüência para métodos pequenos).
Resumindo
- Tanto em C ++ quanto em Java, verificar se argumentos opcionais são nulos faz parte da lógica do programa.
- Em C ++, eu sempre verifico argumentos obrigatórios para garantir que uma exceção apropriada seja lançada para que o programa possa lidar com isso de maneira robusta.
- Em Java (ou C #), eu verificaria argumentos obrigatórios se houver caminhos de execução que não serão lançados para ter uma forma mais strong de "falhar cedo".
EDITAR
Obrigado ao Stilgar para mais detalhes.
No seu caso, parece que você tem null como resultado de um método. Mais uma vez, acho que você deve primeiro esclarecer (e corrigir) a semântica de seus métodos antes
você pode tomar uma decisão.
Então, você tem o método m1 () chamando o método m2 () e m2 () retorna uma referência
(em Java) ou um ponteiro (em C ++) para algum objeto.
Qual é a semântica de m2 ()?
Deve m2 () sempre retornar um resultado não nulo? Se este for o caso, então um resultado nulo é um erro interno (em m2 ()).
Se você verificar o valor de retorno em m1 (), poderá ter um tratamento de erros mais robusto. Se você não fizer isso, provavelmente terá uma exceção, mais cedo ou mais tarde. Talvez não. Espero que a exceção seja lançada durante o teste e não após a implantação. Pergunta : se m2 () nunca deve retornar null, por que ele está retornando null? Talvez devesse lançar uma exceção em vez disso? m2 () é provavelmente buggy.
A alternativa é que retornar null faz parte da semântica do método m2 (), ou seja, possui um resultado opcional, que deve ser documentado na documentação Javadoc do método. Nesse caso, é OK ter um valor nulo. O método m1 () deve verificá-lo como qualquer outro valor: não há erro aqui, mas provavelmente verificar se o resultado é nulo é apenas parte da lógica do programa.