Veja os dois exemplos de código:
if(optional.isPresent()) {
//do your thing
}
if(variable != null) {
//do your thing
}
Tanto quanto posso dizer, a diferença mais óbvia é que o Opcional requer a criação de um objeto adicional.
No entanto, muitas pessoas começaram a adotar rapidamente os opcionais. Qual é a vantagem de usar opcionais versus uma verificação nula?
if
declarações são muuuuito última década, e todo mundo está usando abstrações de mônada e lambdas agora.if(x.isPresent) fails_on_null(x.get)
sair do sistema de tipos, é necessário manter a garantia de que o código não irá "entrar na sua cabeça" pela distância (reconhecidamente curta) entre a condição e a chamada de função. Nooptional.ifPresent(fails_on_null)
sistema de tipos faz essa garantia para você, e você não precisa se preocupar.Optional.ifPresent
(e várias outras construções Java) é que você só pode modificar efetivamente variáveis finais e não pode lançar exceções verificadas. Essa é a razão suficiente para evitar frequentementeifPresent
, infelizmente.Respostas:
Optional
aproveita o sistema de tipos para realizar um trabalho que, de outra forma, você teria que fazer tudo em sua mente: lembrando se uma determinada referência pode ou não sernull
. Isso é bom. É sempre inteligente deixar o compilador lidar com drogas entediantes e reservar o pensamento humano para um trabalho criativo e interessante.Sem
Optional
, toda referência em seu código é como uma bomba não explodida. Acessá-lo pode fazer algo útil, ou pode encerrar seu programa com uma exceção.Com Opcional e sem
null
, todos os acessos a uma referência normal são bem-sucedidos e todas as referências a um Opcional são bem-sucedidos, a menos que esteja desativado e você não tenha verificado isso. Essa é uma grande vitória em manutenção.Infelizmente, a maioria dos idiomas que agora oferecem
Optional
não foi abolidanull
; portanto, você só pode lucrar com o conceito instituindo uma política estrita de "absolutamentenull
nunca". Portanto,Optional
por exemplo, Java não é tão atraente quanto deveria ser idealmente.fonte
Optional
apenas para lembrá-lo que o valor pode ser nuloUm
Optional
traz uma digitação mais forte em operações que podem falhar, como as outras respostas abordaram, mas isso está longe de ser a coisa mais interessante ou valiosaOptionals
trazida para a mesa. Muito mais útil é a capacidade de atrasar ou evitar a verificação de falhas e de compor facilmente muitas operações que podem falhar.Considere se você teve sua
optional
variável do código de exemplo e precisou executar duas etapas adicionais que podem falhar potencialmente. Se alguma etapa ao longo do caminho falhar, você deseja retornar um valor padrão. UsandoOptionals
corretamente, você acaba com algo assim:Com
null
eu teria que verificar três vezesnull
antes de prosseguir, o que adiciona muita complexidade e dores de cabeça de manutenção ao código.Optionals
ter essa verificação incorporada às funçõesflatMap
eorElse
.Observe que eu não liguei
isPresent
uma vez, o que você deve considerar um cheiro de código ao usarOptionals
. Isso não significa necessariamente que você nunca deve usarisPresent
, apenas que você deve examinar fortemente qualquer código que faça isso, para ver se há uma maneira melhor. Caso contrário, você está certo, apenas obtém um benefício de segurança do tipo marginal em relação ao usonull
.Observe também que não estou tão preocupado em encapsular tudo isso em uma única função, a fim de proteger outras partes do meu código de ponteiros nulos de resultados intermediários. Se faz mais sentido ter minha
.orElse(defaultValue)
outra função, por exemplo, tenho muito menos escrúpulos em colocá-la lá, e é muito mais fácil compor as operações entre diferentes funções, conforme necessário.fonte
Ele destaca a possibilidade de nulo como uma resposta válida, que as pessoas geralmente assumem (com ou sem razão) não será retornada. Destacar as poucas vezes em que nulo é válido permite omitir seu código com muitos números de verificações nulas inúteis.
Idealmente, definir uma variável como null seria um erro de tempo de compilação em qualquer lugar, exceto em um opcional; eliminando exceções de ponteiro nulo em tempo de execução. Obviamente, a compatibilidade com versões anteriores impede isso, infelizmente
fonte
Deixe-me lhe dar um exemplo:
É bastante claro para que serve esse método. Mas o que acontece se o repositório não contém usuário com o ID fornecido? Poderia lançar uma exceção ou talvez retorne nulo?
Segundo exemplo:
Agora, o que acontece aqui se não houver usuário com o ID fornecido? Certo, você obtém a instância Optional.absent () e pode verificá-la com Optional.isPresent (). A assinatura do método com Opcional é mais explícita sobre seu contrato. É imediatamente claro como o método deve se comportar.
Também tem um benefício ao ler o código do cliente:
Treinei meus olhos para ver .get () como um cheiro de código imediato. Isso significa que o cliente intencionalmente ignora o contrato do método invocado. É muito mais fácil ver isso do que sem o Opcional, porque nesse caso você não sabe imediatamente qual é o contrato do método chamado (se ele permite nulo ou não em seu retorno); portanto, é necessário verificar primeiro.
Opcional é usado com a convenção de que métodos com tipo de retorno Opcional nunca retornam nulo e geralmente também com a convenção (menos forte) de que o método sem Tipo de retorno opcional nunca retorna nulo (mas é melhor anotá-lo com @Nonnull, @NotNull ou similar) .
fonte
Um
Optional<T>
permite que você tenha "falha" ou "nenhum resultado" como um valor de resposta / retorno válido para seus métodos (pense, por exemplo, em uma pesquisa no banco de dados). Usar um emOptional
vez de usarnull
para indicar falha / nenhum resultado tem algumas vantagens:null
pode ser retornado.null
, pelo menos na minha opinião, não deve ser usado para indicar nada, pois a semântica pode não ser totalmente clara. Deve ser usado para informar ao coletor de lixo que o objeto referido anteriormente pode ser coletado.Optional
classe fornece muitos métodos legais para trabalhar condicionalmente com os valores (por exemplo,ifPresent()
) ou definir valores padrão de maneira transparente (orElse()
).Infelizmente, isso não elimina completamente a necessidade de
null
verificações no código, pois oOptional
objeto em si ainda pode estarnull
.fonte
Além das outras respostas, a outra grande vantagem dos Opcionais quando se trata de escrever código limpo é que você pode usar uma expressão Lambda no caso de o valor estar presente, conforme mostrado abaixo:
fonte
Considere o seguinte método:
Agora, vamos ver um código de chamada:
Isso causa uma falha potencialmente difícil de rastrear em outro lugar, porque
dance
não esperava um nulo.Isso causa um erro de compilação, porque a dança esperava um
Person
não umOptional<Person>
Se eu não tivesse uma pessoa, isso causaria uma exceção nessa linha, no ponto em que eu tentava convertê-la ilegalmente
Optional<Person>
em uma Pessoa. A chave é que, ao contrário de passar um nulo, o exceto rastreia até aqui, não em outro local no programa.Para juntar tudo: o uso incorreto de opcionais produz problemas mais fáceis de localizar, o uso nulo causa problemas difíceis de localizar.
fonte
Optional.get()
seu código, ele é mal gravado - você quase nunca deve chamar Optional.get sem verificarOptional.isPresent()
primeiro (como indicado no OP) ou pode escreveroptionalPersion.ifPresent(myObj::dance)
.No Objective-C, todas as referências a objetos são opcionais. Por causa disso, o código como você postou é bobo.
Código como o acima é inédito no Objective-C. Em vez disso, o programador iria apenas:
E se
variable
contiver um valor,doThing
será chamado nele. Caso contrário, não há mal. O programa o tratará como não operacional e continuará sendo executado.Esse é o benefício real dos opcionais. Você não precisa desarrumar seu código
if (obj != nil)
.fonte
O problema óbvio aqui é que se "opcional" realmente estiver ausente (ou seja, for nulo), seu código explodirá com uma NullReferenceException (ou similar) tentando chamar qualquer método em uma referência de objeto nulo!
Você pode escrever um método estático, da classe Helper, que determine a nulidade de qualquer tipo de objeto, algo como isto:
ou, talvez, mais útil:
Mas será que algum deles é realmente mais legível / compreensível / sustentável do que o original?
fonte