Um booleano Java pode ser usado para lógica ternária (estado 3)?

5

Estou tentando fazer um cache básico de um valor booleano, e fiz assim:

private Boolean _valueCache = null;
private boolean getValue() {
    try {
        if (_valueCache == null) { // if cache was never filled
            return _valueCache = getReader().getMyBooleanProperty(); // fill it and return the new value
        }
        return _valueCache; // else, return the cache
    } catch (NullPointerException ex) { // getReader() returned null
        return false; // that return may not be null in the future, so set nothing
    }
}

Isso vai contra as práticas recomendadas? (permitindo que um Boolean tenha 3 valores: true , false e null ) Eu só quero armazenar esse valor em cache, então Não quero criar um HashMap personalizado inteiro que imite esse comportamento com um método get ou padrão. Dito isso, eu nunca fiz um cache tão pequeno, então não sei as desvantagens dele.

Para esclarecer , quis dizer "ternário" como em "estado 3", em oposição a "binário" como em "estado 2". Desculpe por qualquer confusão.

    
por Ben Leggiero 05.03.2015 / 16:47
fonte

3 respostas

7

Você não está fazendo lógica ternária, apenas está usando null como um espaço reservado para um valor ausente que é do tipo Boolean . (Não ter true nem false não é exatamente o mesmo que ter um dos dois, mas não saber qual). Usar null dessa forma é uma prática bastante comum, mas Eu não chamaria isso de bom .

É improvável que isso lhe cause problemas neste caso em particular, porque ele é usado apenas internamente em um escopo muito pequeno, mas em geral você desejaria usar Opcional . Como qualquer variável não primitiva pode ter null , é muito difícil rastreá-la em uma base de código grande. A maneira mais fácil de evitar o problema é não usar null em primeiro lugar.

    
por 05.03.2015 / 17:07
fonte
2

Embora o uso de null ou o uso de um Optional sejam opções razoáveis, uma opção a mais seria adicionar um segundo campo explícito, boolean _hasBeenRead . Seu código ficaria parecido com

private boolean getValue() {
    if (_hasBeenRead)
       return _valueCache;

    else {
       // read the value and, if successful, set both _hasBeenRead and _valueCache.
    }
}

Alguns considerariam isso mais explícito e, portanto, mais claro. Especialmente se você estiver usando o estilo antigo Java sem novos itens como o Optional.

p.s. Faça o que fizer, considere se esse método precisa ser sincronizado, se as variáveis precisam ser voláteis, etc ...

    
por 05.03.2015 / 23:37
fonte
-2

A lógica tenencial para isso deve ser

private Boolean _valueCache = null;
private boolean getValue() { 
         Boolean readerValue = getReader() == null ? false : reader.getMyBooleanProperty();
         _valueCache = _valueCache == null  ? readerValue : _valueCache; 
         return _valueCache;

   }

By the way, o que é o uso da exceção NullPointer tratado, Será que o getReader () retornar null, exceções de tempo de execução como este também não são aconselháveis

    
por 06.03.2015 / 23:45
fonte