问题
This is sorta' a two-part question.
I have a person object with a char attribute on it called "active". Person has a getActive() method that returns a char as expected. In my JSTL EL, I have the following:
<c:if test="${person.active == '1'}">Active</c:if>
This never passes. My understanding is that quoted literals in JSTL are strings (regardless of single or double quote) and that the char type is being retained from the getActive call, so these two values are not equal when getActive() returns the character '1'.
As an alternative, I added an isActive() method which returns a boolean. In this case, the following works:
<c:if test="${person.active == true}">Active</c:if>
Here are my questions:
- Is my understanding correct regarding the char comparison? If so, is there any way to convert the types in JSTL so that they are comparable?
- When both getActive() and isActive() exist, which one gets called by the EL translation? It seems isActive() gets priority but is there an officially documented ordering to this?
回答1:
Is my understanding correct regarding the char comparison? If so, is there any way to convert the types in JSTL so that they are comparable?
From chapter 1.8.2 of EL 2.2 specification (emphasis mine):
1.8.2
A {==,!=,eq,ne} B
- If
A==B
, apply operator- If
A
isnull
orB
isnull
returnfalse
for==
oreq
,true
for!=
orne
.- If
A
orB
isBigDecimal
, coerce bothA
andB
toBigDecimal
and then:
- If operator is
==
oreq
, returnA.equals(B)
- If operator is
!=
orne
, return!A.equals(B)
- If
A
orB
isFloat
orDouble
coerce bothA
andB
toDouble
, apply operator- If
A
orB
isBigInteger
, coerce bothA
andB
toBigInteger
and then:
- If operator is
==
oreq
, returnA.equals(B)
- If operator is
!=
orne
, return!A.equals(B)
- If
A
orB
isByte
,Short
,Character
,Integer
, orLong
coerce bothA
andB
toLong
, apply operator- If
A
orB
isBoolean
coerce bothA
andB
toBoolean
, apply operator- If
A
orB
is anenum
, coerce bothA
andB
toenum
, apply operator- If
A
orB
isString
coerce bothA
andB
toString
, compare lexically- Otherwise if an error occurs while calling
A.equals(B)
, error- Otherwise, apply operator to result of
A.equals(B)
The char
/Character
is in EL thus coerced and evaluated as Long
. That can never equal to a string literal of '1'
.
When both getActive() and isActive() exist, which one gets called by the EL translation? It seems isActive() gets priority but is there an officially documented ordering to this?
From chapter 8.3.2 of Javabeans specification (emphasis mine):
8.3.2 Boolean properties
In addition, for boolean properties, we allow a getter method to match the pattern:
public boolean is<PropertyName>()
;This “is<PropertyName>” method may be provided instead of a “get<PropertyName>” method, or it may be provided in addition to a “get<PropertyName>” method.
In either case, if the “is<PropertyName>” method is present for a boolean property then we will use the “is<PropertyName>” method to read the property value.
An example boolean property might be:
public boolean isMarsupial(); public void setMarsupial(boolean m);
This, in combination with the point right after the emphasized point in the previously quoted chapter 1.8.2 of EL spec,
- If
A
orB
isBoolean
coerce bothA
andB
toBoolean
, apply operator
will give the isXxx()
method precedence.
回答2:
What you can do is test the character's value, something like
<c:if test="${person.active.value == 1}">Active</c:if>
As to which one gets priority isXXX() or getXXX() it's pretty much implementation specific.
来源:https://stackoverflow.com/questions/9467191/jstl-el-accessor-translation-priority-when-get-and-is-both-exist