Сравнение строки и логического значения в языке выражений - PullRequest
9 голосов
/ 17 ноября 2011

У меня такое поведение, я не очень понимаю

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

выходы

false
java.lang.Boolean
true
  1. Как это может быть exlpained?
  2. Что это правильноспособ написать тест, чтобы сначала проверить, имеют ли две «вещи» одинаковый тип, а затем, если их значение одинаково?

Ответы [ 3 ]

14 голосов
/ 17 ноября 2011

Это поведение языка, определенное в спецификации EL :

A {==,! =, Eq, ne} B

  • другие правила исключены
  • Если A или B - логическое значение, и A и B - логическое значение, примените оператор

Coerce A к логическому значение

  • Если A является нулем или "", вернуть false
  • В противном случае, если A является логическим значением, вернуть A
  • В противном случае, , если A является строкой,и Boolean.valueOf (A) не выдает исключение, возвращает его
  • В противном случае ошибка

Таким образом, строковый литерал приводится к логическому значению черезBoolean.valueOf("error") который возвращает false .

6 голосов
/ 17 ноября 2011

Если одна из двух сторон в EL - это Boolean (или boolean), а другая сторона - String, тогда String будет проанализирован до Boolean с помощью Boolean#valueOf(), чья javadoc говорит следующее:

Возвращает Boolean со значением, представленным указанной строкой. Возвращаемое значение Boolean представляет значение true, если строковый аргумент не равен null и равен (без учета регистра) строке "true".

Итак, он возвращает false, и это действительно равно false.

Вам нужно переписать выражение EL, чтобы учесть, что тип может быть как логическим, так и строковым, или просто придерживаться одного типа, а не смешивать типы в одном атрибуте.

0 голосов
/ 18 ноября 2011

Что касается пункта 2.

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

проверит, что две «вещи» являются экземплярами одного и того же класса.

Но может быть лучше преобразовать someVar в строку, а затем сравнить две строки, поскольку (по крайней мере, в моем случае) someVar не гарантированно является строкой или логическим значением, поэтому может быть что-то еще, что можно преобразовать в строку.

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

Какие выходы

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