2011-11-17 11 views
8

mam ten problem tak naprawdę nie rozumiemPorównywanie ciąg i logiczną w języku Expression

${someVar} 
${someVar.class.name}  
${someVar == 'error'} 

wyjść

false 
java.lang.Boolean 
true 
  1. Jak można exlpained?
  2. Jaki jest właściwy sposób napisania testu, aby najpierw sprawdzić, czy dwie "rzeczy" mają ten sam typ, a następnie czy ich wartość jest taka sama?
+1

usunęła stary przypadek testowy i zastąpiono łączącą bardziej zwartą i prostą jeden. – Paolo

+0

Znacznie lepiej ':)' –

Odpowiedz

13

To zachowanie języka, jak określono w EL specification:

odpowiedzi {==, =, eq, ne!} B

  • inne reguły pomijana
  • Jeśli A lub B jest typu Boolean, wymuszaj zarówno A, jak i B na wartość Boolean, zastosuj operatora:

Coerce A Boolean

  • Jeżeli A jest zerowy lub "" return false
  • W przeciwnym razie, jeśli A jest logiczna, zwracają
  • Inaczej jeśli A jest ciągiem znaków, a Boolean.valueOf (A) robi nie wyjątek, zwrócić go
  • w innym wypadku błędu

więc ciąg dosłowny jest rzutowane na wartości logicznej poprzez Boolean.valueOf("error") który returns false.

6

Jeżeli jedna z obu stron EL jest Boolean (lub boolean), a druga strona jest String, wówczas String zostaną przetworzone w celu Boolean przez Boolean#valueOf() którego javadoc mówi następujące:

Zwraca wartość Boolean o wartości reprezentowanej przez określony ciąg. Zwrócony kod Boolean reprezentuje wartość true, jeśli argument łańcucha nie jest równy, ignorując wielkość liter, "ciąg".

Powoduje, że zwraca false i jest to rzeczywiście równa false.

Musisz przepisać swoje wyrażenie EL, aby wziąć pod uwagę, że typ może być zarówno boolowskim i ciągiem, lub po prostu trzymać się jednego typu, a nie mieszać typy w jednym atrybucie.

0

Co do punktu 2.

<c:set var="errorString" value="${'error'}" /> 
${someVar.class == errorString.class} 

sprawdzi, czy dwie „rzeczy” są instancjami tej samej klasy.

Ale lepiej jest przekonwertować someVar na łańcuch, a następnie porównać oba łańcuchy, ponieważ (przynajmniej w moim przypadku) niektóreVar nie ma gwarancji, że jest łańcuchem lub boolowcem, więc może to być cokolwiek innego, co może przekonwertować na ciąg.

<c:set var="strsomeVar">${someVar}</c:set> 
//${someVar} 
//${someVar.class} 
//${someVar == 'error'} 

które wyjścia

//false 
//class java.lang.String 
//false