Eu tenho um método que deve retornar um objeto se ele for encontrado.
Se não for encontrado, devo:
- retornar nulo
- lançar uma exceção
- de outros
exception
error-handling
null
Robert
fonte
fonte
Respostas:
Se você está sempre esperando encontrar um valor, lance a exceção, se estiver faltando. A exceção significaria que havia um problema.
Se o valor estiver ausente ou presente e ambos forem válidos para a lógica do aplicativo, retorne um valor nulo.
Mais importante: o que você faz em outros lugares no código? A consistência é importante.
fonte
GetPersonById(25)
jogaria se essa pessoa fosse excluída, masGetPeopleByHairColor("red")
retornaria um resultado vazio. Então, acho que os parâmetros dizem algo sobre as expectativas.Lance uma exceção apenas se for realmente um erro. Se o comportamento esperado para o objeto não existir, retorne o valor nulo.
Caso contrário, é uma questão de preferência.
fonte
Como regra geral, se o método sempre retornar um objeto, vá com a exceção. Se você antecipar o nulo ocasional e quiser lidar com isso de uma certa maneira, vá com o nulo.
Faça o que fizer, desaconselho a terceira opção: retornar uma sequência que diz "WTF".
fonte
Se nulo nunca indicar um erro, basta retornar nulo.
Se nulo é sempre um erro, lance uma exceção.
Se null for algumas vezes uma exceção, codifique duas rotinas. Uma rotina lança uma exceção e a outra é uma rotina de teste booleana que retorna o objeto em um parâmetro de saída e a rotina retorna false se o objeto não foi encontrado.
É difícil usar mal a rotina Try. É muito fácil esquecer de verificar se há nulo.
Então, quando nulo é um erro, basta escrever
Quando o nulo não é um erro, você pode codificar algo como
fonte
find
efindOrFail
de Laravel EloquentTryFindObject
método? As tuplas parecem um paradigma preguiçoso para programadores que não desejam reservar um tempo para definir um objeto que encapsule vários valores. Isso é essencialmente todas as tuplas estão no centro de qualquer maneira.Eu só queria recapitular as opções mencionadas anteriormente, lançando algumas novas em:
Ou você pode combinar estas opções:
Forneça várias versões sobrecarregadas do seu getter, para que o chamador possa decidir qual caminho seguir. Na maioria dos casos, apenas o primeiro tem uma implementação do algoritmo de pesquisa e os outros apenas envolvem o primeiro:
Mesmo se você optar por fornecer apenas uma implementação, convém usar uma convenção de nomenclatura como essa para esclarecer seu contrato, e isso ajudará você a decidir adicionar outras implementações também.
Você não deve usá-lo em excesso, mas pode ser útil, especialmente ao escrever uma classe auxiliar que você usará em centenas de aplicativos diferentes, com muitas convenções diferentes de tratamento de erros.
fonte
Expected<T> findObject(String)
ondeExpected<T>
tem as funçõesorNull()
,orThrow()
,orSupplied(Supplier<T> supplier)
,orDefault(T default)
. Isso abstrai a obtenção dos dados do tratamento de erros.Use o padrão de objeto nulo ou lance uma exceção.
fonte
Person somePerson = personRepository.find("does-not-exist");
vamos supor que esse método retorne um objeto nulo para o IDdoes-not-exist
. Qual seria então o comportamento corretosomePerson.getAge()
? No momento, ainda não estou convencido de que o padrão de objeto nulo seja a solução certa para pesquisas de entidade.Seja consistente com as APIs que você está usando.
fonte
Vantagens de lançar uma exceção:
Para obter mais explicações com exemplos, consulte: http://metatations.com/2011/11/17/returning-null-vs-throwing-an-exception/
fonte
depende se seu idioma e código promoverem: LBYL (olhe antes de pular) ou EAFP (mais fácil pedir perdão do que permissão)
O LBYL diz que você deve verificar os valores (portanto, retorne um nulo) O
EAFP diz apenas para tentar a operação e ver se ela falha (lança uma exceção)
embora eu concorde com o acima. exceções devem ser usadas para condições excepcionais / de erro, e retornar um nulo é melhor ao usar verificações.
EAFP vs. LBYL em Python:
http://mail.python.org/pipermail/python-list/2003-May/205182.html ( arquivo da web )
fonte
Apenas pergunte a si mesmo: "é um caso excepcional que o objeto não foi encontrado"? Se é esperado que isso aconteça no curso normal do seu programa, você provavelmente não deve gerar uma exceção (já que não é um comportamento excepcional).
Versão curta: use exceções para lidar com um comportamento excepcional, não para lidar com o fluxo normal de controle em seu programa.
Alan.
fonte
As exceções estão relacionadas ao Design por contrato.
A interface de um objeto é na verdade um contrato entre dois objetos, o chamador deve cumprir o contrato ou o receptor pode apenas falhar com uma exceção. Existem dois contratos possíveis
1) todas as entradas que o método é válido; nesse caso, você deve retornar nulo quando o objeto não for encontrado.
2) apenas alguma entrada é válida, ou seja, a que resulta em um objeto encontrado. Nesse caso, você DEVE oferecer um segundo método que permita ao chamador determinar se sua entrada estará correta. Por exemplo
SE e SOMENTE SE você fornecer os dois métodos do 2º contrato, você poderá lançar uma exceção se nada for encontrado!
fonte
Prefiro apenas retornar um nulo e confiar no chamador para lidar com isso adequadamente. A exceção (por falta de uma palavra melhor) é se estou absolutamente "certo" de que esse método retornará um objeto. Nesse caso, uma falha é excepcional e deve ser lançada.
fonte
Depende do que significa que o objeto não foi encontrado.
Se for um estado normal, retorne nulo. Isso é apenas algo que pode acontecer de vez em quando, e os chamadores devem verificar isso.
Se for um erro, em seguida, lançar uma exceção, os chamadores devem decidir o que fazer com a condição de erro do objeto ausente.
Em última análise, ambos funcionariam, embora a maioria das pessoas considere geralmente uma boa prática usar apenas exceções quando algo, bem, excepcional aconteceu.
fonte
Aqui estão mais algumas sugestões.
Se retornar uma coleção, evite retornar nulo, retorne uma coleção vazia que facilite o processamento da enumeração sem uma verificação nula.
Várias APIs .NET usam o padrão de um parâmetro thrownOnError que permite ao chamador escolher se é realmente uma situação excepcional ou não, se o objeto não for encontrado. Type.GetType é um exemplo disso. Outro padrão comum com BCL é o padrão TryGet, em que um booleano é retornado e o valor é passado através de um parâmetro de saída.
Você também pode considerar o padrão Null Object em algumas circunstâncias, que podem ser um padrão ou uma versão sem comportamento. A chave é evitar verificações nulas em toda a base de código. Veja aqui para mais informações http://geekswithblogs.net/dsellers/archive/2006/09/08/90656.aspx
fonte
Em algumas funções, adiciono um parâmetro:
Verdadeiro significa jogar, falso significa retornar algum valor de retorno de erro. Dessa forma, quem usa essa função possui as duas opções. O padrão deve ser verdadeiro, para o benefício daqueles que esquecem o tratamento de erros.
fonte
Retorne um nulo em vez de lançar uma exceção e documente claramente a possibilidade de um valor de retorno nulo na documentação da API. Se o código de chamada não respeitar a API e verificar o caso nulo, provavelmente resultará em algum tipo de "exceção de ponteiro nulo" de qualquer maneira :)
Em C ++, posso pensar em três tipos diferentes de configuração de um método que encontra um objeto.
Opção A
Retorne nulo quando um objeto não puder ser encontrado. Agradável e simples. Eu iria com este. As abordagens alternativas abaixo são para pessoas que não odeiam parâmetros exagerados.
Opção B
Passe uma referência à variável que estará recebendo o objeto. O método gerou uma exceção quando um objeto não pode ser encontrado. Essa convenção provavelmente é mais adequada se não for realmente esperado que um objeto não seja encontrado - portanto, você lança uma exceção para indicar que é um caso inesperado.
Opção C
O método retorna false quando um objeto não pode ser encontrado. A vantagem dessa opção A é que você pode verificar o caso de erro em uma etapa clara:
fonte
referindo-me apenas ao caso em que nulo não é considerado um comportamento excepcional, eu definitivamente sou o método try, é claro, não há necessidade de "ler o livro" ou "olhar antes de pular", como foi dito aqui
então, basicamente:
e isso significa que o código do usuário também ficará claro
fonte
Se é importante que o código do cliente saiba a diferença entre encontrado e não encontrado e esse seja um comportamento de rotina, é melhor retornar nulo. O código do cliente pode decidir o que fazer.
fonte
Geralmente, ele deve retornar nulo. O código que chama o método deve decidir se deve lançar uma exceção ou tentar outra coisa.
fonte
Ou retorne uma opção
Uma opção é basicamente uma classe de contêiner que força o cliente a lidar com casos de booth. Scala tem esse conceito, procure sua API.
Então você tem métodos como T getOrElse (T valueIfNull) nesse objeto para retornar o objeto encontrado ou uma alternativa às especificações do cliente.
fonte
Prefere retornar null -
Se o chamador o usa sem verificar, a exceção acontece exatamente assim.
Se o chamador não o usar, não taxe um bloco
try
/catch
fonte
Infelizmente, o JDK é inconsistente. Se você tentar acessar uma chave inexistente no pacote de recursos, não encontrará uma exceção e, ao solicitar o valor do mapa, será nulo se ele não existir. Então, eu mudaria a resposta do vencedor da seguinte forma: se o valor encontrado puder ser nulo, geraria uma exceção quando não for encontrado; caso contrário, retorne nulo. Portanto, siga a regra com uma exceção, se você precisar saber por que o valor não é encontrado, sempre aumente a exceção ou ..
fonte
Desde que deva retornar uma referência ao objeto, retornar um NULL deve ser bom.
No entanto, se estiver retornando a coisa toda sangrenta (como em C ++, se você fizer: 'return blá;' em vez de 'return blá;' (ou 'blá' é um ponteiro), não será possível retornar um NULL, porque é não do tipo 'objeto'. Nesse caso, lançar uma exceção ou retornar um objeto em branco que não possui um sinalizador de sucesso definido é como eu abordaria o problema.
fonte
Não pense que alguém mencionou a sobrecarga no tratamento de exceções - gasta recursos adicionais para carregar e processar a exceção, a menos que seja um verdadeiro evento de interrupção ou interrupção do processo de aplicativos (daqui para frente causaria mais danos do que benefícios). valor que o ambiente de chamada poderia interpretar como entender.
fonte
Concordo com o que parece ser o consenso aqui (retornar nulo se "não encontrado" for um resultado possível normal ou lançar uma exceção se a semântica da situação exigir que o objeto seja sempre encontrado).
Há, no entanto, uma terceira possibilidade que pode fazer sentido, dependendo da sua situação particular. Seu método pode retornar um objeto padrão de algum tipo na condição "não encontrado", permitindo que o código de chamada tenha certeza de que sempre receberá um objeto válido sem a necessidade de verificação nula ou captura de exceção.
fonte
Retorne um nulo, as exceções são exatamente isso: algo que seu código faz que não é esperado.
fonte
Exceções devem ser excepcionais . Retorne nulo se for válido retornar um nulo .
fonte
Se o método retornar uma coleção, retorne uma coleção vazia (como dito acima). Mas não use Collections.EMPTY_LIST ou algo semelhante! (no caso de Java)
Se o método recuperar um único objeto, você terá algumas opções.
Cuidado, se você decidir retornar um nulo. Se você não é o único programador do projeto, receberá NullPointerExceptions (em Java ou qualquer outra linguagem) em tempo de execução! Portanto, não retorne nulos que não são verificados no momento da compilação.
fonte
null
. Veja a resposta mais votada para obter mais.Se você estiver usando uma biblioteca ou outra classe que lança uma exceção, você deve repeti- la novamente . Aqui está um exemplo. Example2.java é como biblioteca e Example.java usa seu objeto. Main.java é um exemplo para lidar com essa exceção. Você deve mostrar uma mensagem significativa e (se necessário) empilhar o rastreamento para o usuário no lado de chamada.
Main.java
Example.java
Example2.java
fonte
Isso realmente depende se você espera encontrar o objeto ou não. Se você seguir a escola de pensamento de que exceções devem ser usadas para indicar algo, bem, erre, excepcional ocorreu:
Caso contrário, retorne nulo.
fonte