Primeiro a situação que funciona:
[code]Boolean
lb;
int
ln1 = 1,
ln2 = 2;
lb = ln1 == ln2
? true
: null;[/code]
Segundo a situação que não funciona:
[code]Boolean
lb;
int
ln1 = 1,
ln2 = 2;
lb
= ln1 == 0
? false
: ln2 == 5
? true
: null
;[/code]
A segunda, ocorre NullPointerException. Alguem sabe me informar o motivo ?
Realmente intrigante, mas acho que deve ter algo a ver com o AutoBoxing.
Note que assim não dá erro:
[code] Boolean lb;
int ln1 = 1, ln2 = 2;
lb = ln1 == 0 ? Boolean.FALSE : ln2 == 5 ? Boolean.TRUE : null;[/code]
Só um comentário… isso não é um “if com inline”, mas o operador ternário.
Esse operador espera o mesmo tipo de dado de ambos os lados do :
Talvez esteja aí a solução do problema.
Já tinha encontrado essa situação:
[code]Boolean lb;
int ln1 = 1, ln2 = 2;
lb = ln1 == 0 ? Boolean.FALSE : ln2 == 5 ? Boolean.TRUE : null;[/code]
Porém estou utilizando o java 6 e não deveria necessitar o uso de Boolean.FALSE e Boolean.TRUE.
Seria isso bug do Java ?
Obs: Operador ternario é uma forma compacta de expressar o if e else, ou seja, o mesmo que if in-line… ou não ?
É que a palavra inline não é sinônimo para "curto". De qualquer forma, esse operador não é exatamente igual a um if, pq ele exige o retorno de um valor. Você não pode simplesmente fazer:
void x() {
}
void y() {
}
int a = 10;
a < 10 ? x() : y();
Que dá erro.
Claro.
Mas então, o que seria um if inline para você ?
Inline é um código que depois de compilado irá desaparecer. Para mim, um if inline seria analisado em tempo de compilação e só o resultado seria colocado no binário final.
Mas enfim, acho que estamos fugindo do ponto aqui. Ainda estou curioso para saber de onde vem esse NullPointerException. O que acontece é que com Boolean.TRUE e Boolean.FALSE o Java não fará auto-boxing, e por isso, o erro não ocorre.
Ainda assim, eu esperaria que o compilador fosse mais esperto que isso, ou será que meu chute está errado?
Poisé,
também achava que o compilador seria esperto o suficiente para identificar essa situação.
Hum…
O programa é equivalente a este aqui:
class TesteInline {
public static void main(String[] args) {
Boolean lb;
int ln1 = 1, ln2 = 2;
boolean t = (ln2 == 5 ? true : null); // aqui ocorre a NullPointerException, pois null não pode ser "unboxed" para true ou false
lb = (ln1 == 0 ? false : t);
}
}
Quando na verdade você acharia que ele seria equivalente a este aqui:
class TesteInline {
public static void main(String[] args) {
Boolean lb;
int ln1 = 1, ln2 = 2;
Boolean t = (ln2 == 5 ? true : null);
lb = (ln1 == 0 ? Boolean.FALSE : t);
}
}
Pensem mais um pouco. Dá a impressão que é algum lado obscuro das regras de “autoboxing” que interferem com a resolução de tipos no “?”. Pode até ser algum bug esquisito do compilador.
Achei muito bom isso!
Fiz um teste com String:
[code]String
ls;
int
ln1 = 1,
ln2 = 2;
ls
= ln1 == 0
? “false”
: ln2 == 5
? “true”
: null
;[/code]
Perfeito!
[quote=Matheus Leandro Ferreira]Achei muito bom isso!
Fiz um teste com String:
[code]String
ls;
int
ln1 = 1,
ln2 = 2;
ls
= ln1 == 0
? “false”
: ln2 == 5
? “true”
: null
;[/code]
Perfeito![/quote]
POG!
O problema é que não é possivel atribuir o valor null a tipos primitivos.
Eu não testei mas isso funciona com int, double, etc?
[quote=Mark_Ameba][quote=Matheus Leandro Ferreira]Achei muito bom isso!
Fiz um teste com String:
[code]String
ls;
int
ln1 = 1,
ln2 = 2;
ls
= ln1 == 0
? “false”
: ln2 == 5
? “true”
: null
;[/code]
Perfeito![/quote]
POG!
O problema é que não é possivel atribuir o valor null a tipos primitivos.
Eu não testei mas isso funciona com int, double, etc?[/quote]
Exato, mas o boolean que utilizei não era primitivo e sim Objeto. (podendo receber valor null)
só com o tipo Boolean da problema! mas o lance é separar as situações mesmo… bug loco no compilador.
Outro problema que encontrei foi esse… Comparando wrappers:
[code]Integer x = 120;
Integer y = 120;
System.out.println(x == y); // true
Integer w = -128;
Integer z = -128;
System.out.println(w == z); // true
Mas quando utilizo -129:
Integer g = -129;
Integer h = -129;
System.out.println(g ==h); // false[/code]
Obs: Quando você usa == para comparar, ele acaba comparando a referencia do objeto e utilizando o método equals() ele compara o valor.
Obs2: Fui atras disso… isso seria um foro na implementação do Flyweight Pattern ???
eu li algo a respeito disso, acho que tem a ver com o fato de 129 não caber em um byte… (caia até na certificação acho) vou dar uma procurada e depois posto aqui
Lembro de ver isso em tópicos bem antigos do GUJ. Mas lembro que após 128 o Integer já aloca um novo espaço. Não lembro direito. Tem que procurar mesmo.
http://www.guj.com.br/posts/list/120688.java diz qual é o limite (-128 a +127) que Integer.valueOf usa para retornar um novo objeto Integer, ou então usar um do cache.