Сравнение string и boolean в языке выражений

у меня такое поведение, которое я действительно не понимаю

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

выходы

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

3 ответов


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

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

  • другие правила elided
  • если A или B является Булевым принуждением A и B к Булеву, примените оператор

принудить A к Boolean

  • если A равно null или "", верните false
  • в противном случае, если A является логическим, верните a
  • иначе если A-строка и логическое значение.valueOf (A) не выбрасывает исключение, возвращает его
  • в противном случае, ошибка

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


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

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

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

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


что касается пункта 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