本帖最后由 yuchengmin 于 2018-11-15 20:49 编辑
EL表达式取值数据类型
引言: 需要用el表达式取值的数据,除了对象,最好都是String类型 jsp EL表达式中的int、float、char 在EL表达式计算过程中:
1、所有的整数数字字面量都是Long类型的; 2、所有小数字面量都是Double类型的; 3、""或''声明的是字符串,即''也是字符串,非char; 4、比较时都是equals比较。 例题: 1、 如${1+2147483647} 结果是多少? 如果在java程序里边运行会得到-2147483648,而在jsp el中会得到2147483648。
2、 <% Map<Object, Object> map = new HashMap<Object, Object>(); map.put(new Long(1), 123); request.setAttribute("map", map); request.setAttribute("a", new Long(1)); %> ${map[1]} 正确 ${map[a]} 正确
3、 <% Map<Object, Object> map = new HashMap<Object, Object>(); map.put(new Integer(1), 123); request.setAttribute("map", map); request.setAttribute("a", new Long(1)); request.setAttribute("b", new Integer(1)); %> ${map[1]} 错误 ${map[a]} 错误 ${map} 正确
4、 <% Map<Object, Object> map = new HashMap<Object, Object>(); map.put(1.1, 123); //map.put(1.1d, 123); request.setAttribute("map", map); request.setAttribute("a", new Double(1.1)); %> map.a=${map[1.1]} 正确 map.a=${map[a]} 正确
5、 <% Map<Object, Object> map = new HashMap<Object, Object>(); map.put(1.1f, 123); //map.put(new Float(1.1), 123); request.setAttribute("map", map); request.setAttribute("a", new Double(1.1)); request.setAttribute("b", new Float(1.1)); %> map.a=${map[1.1]} 错误 map.a=${map[a]} 错误 map.a=${map} 正确
补充: 在EL表达式规范2.2中,定义了: ■ The value of an IntegerLiteral ranges from Long.MIN_VALUE to
Long.MAX_VALUE
■ The value of a FloatingPointLiteral ranges from Double.MIN_VALUE to
Double.MAX_VALUE
在tomcat7.0.6实现中,jasper.jar(实现了EL2.2规范): AstFloatingPoint表示小数,AstInteger表示整数,其定义如下: Java代码: [Java] 纯文本查看 复制代码 public final class AstInteger extends SimpleNode
{
private volatile Number number;
public AstInteger(int id)
{
super(id);
}
protected Number getInteger()
{
if (this.number == null) {
try {
this.number = new Long(this.image);
} catch (ArithmeticException e1) {
this.number = new BigInteger(this.image);
}
}
return this.number;
}
public Class<?> getType(EvaluationContext ctx)
throws ELException
{
return getInteger().getClass();
}
public Object getValue(EvaluationContext ctx)
throws ELException
{
return getInteger();
}
}
Java代码: [Java] 纯文本查看 复制代码 public final class AstFloatingPoint extends SimpleNode
{
private volatile Number number;
public AstFloatingPoint(int id)
{
super(id);
}
public Number getFloatingPoint()
{
if (this.number == null) {
try {
this.number = new Double(this.image);
} catch (ArithmeticException e0) {
this.number = new BigDecimal(this.image);
}
}
return this.number;
}
public Object getValue(EvaluationContext ctx)
throws ELException
{
return getFloatingPoint();
}
public Class<?> getType(EvaluationContext ctx)
throws ELException
{
return getFloatingPoint().getClass();
}
} + - * /实现,此处只看+的: Java代码: [Java] 纯文本查看 复制代码 package org.apache.el.parser;
import javax.el.ELException;
import org.apache.el.lang.ELArithmetic;
import org.apache.el.lang.EvaluationContext;
public final class AstPlus extends ArithmeticNode
{
public AstPlus(int id)
{
super(id);
}
public Object getValue(EvaluationContext ctx)
throws ELException
{
Object obj0 = this.children[0].getValue(ctx);
Object obj1 = this.children[1].getValue(ctx);
return ELArithmetic.add(obj0, obj1);
}
} 其委托给ELArithmetic.add: Java代码: [Java] 纯文本查看 复制代码 public static final DoubleDelegate DOUBLE = new DoubleDelegate();
public static final LongDelegate LONG = new LongDelegate();
private static final Long ZERO = Long.valueOf(0L);
public static final Number add(Object obj0, Object obj1) {
if ((obj0 == null) && (obj1 == null))
return Long.valueOf(0L);
ELArithmetic delegate;
if (BIGDECIMAL.matches(obj0, obj1))
delegate = BIGDECIMAL;
else if (DOUBLE.matches(obj0, obj1))
if (BIGINTEGER.matches(obj0, obj1))
delegate = BIGDECIMAL;
else
delegate = DOUBLE;
else if (BIGINTEGER.matches(obj0, obj1))
delegate = BIGINTEGER;
else {
delegate = LONG;
}
Number num0 = delegate.coerce(obj0);
Number num1 = delegate.coerce(obj1);
return delegate.add(num0, num1);
} 此处委托给了各种delegate计算,其+的实现: Java代码: [Java] 纯文本查看 复制代码 public static final class LongDelegate extends ELArithmetic
{
protected Number add(Number num0, Number num1)
{
return Long.valueOf(num0.longValue() + num1.longValue());
} 从这里我们可以看出其实现。
而且其规范中都规定了具体字面量的东西:
1.3 Literals
There are literals for boolean, integer, floating point, string, and null in an eval-
expression.
■ Boolean - true and false
■ Integer - As defined by the IntegerLiteral construct in Section 1.19
■ Floating point - As defined by the FloatingPointLiteral construct in
Section 1.19
■ String - With single and double quotes - " is escaped as \", ' is escaped as \',
and \ is escaped as \\. Quotes only need to be escaped in a string value enclosed
in the same type of quote
■ Null - null
也规定了操作符的运算规则,如+ - *:
Java代码:
[Java] 纯文本查看 复制代码 1.3 Literals
There are literals for boolean, integer, floating point, string, and null in an eval-expression.
■ Boolean - true and false
■ Integer - As defined by the IntegerLiteral construct in Section 1.19
■ Floating point - As defined by the FloatingPointLiteral construct in
Section 1.19
■ String - With single and double quotes - " is escaped as \", ' is escaped as \',and \ is escaped as \\. Quotes only need to be escaped in a string value enclosed in the same type of quote
■ Null - null
■ If operator is -, return A.subtract(B)
■ If operator is *, return A.multiply(B)
■ If A or B is a Float, Double,or String containing ., e,or E:
■ If A or B is BigInteger, coerce both A and B to BigDecimal and apply operator.
■ Otherwise, coerce both A and B to Double and apply operator
■ If A or B is BigInteger, coerce both to BigInteger and then:
■ If operator is +, return A.add(B)
■ If operator is -, return A.subtract(B)
■ If operator is *, return A.multiply(B)
■ Otherwise coerce both A and B to Long and apply operator
■ If operator results in exception, error
如Integer型,直接交给前边介绍的[size=1em]IntegerLiteral。
|