在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[b]} 正确
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[b]} 正确
6、
结合struts2的ognl表达式
<s:property value="#map = #{'a':123, 'b':234}, ''"/> --->定义一个map,放入值栈的上下文区
<s:property value="#map['a']"/> ---------->正确,因为其支持char
${map['a']} ------------>错误, 因为'a'在jsp el表达式中是字符串,不能=char。
<s:property value='#map = #{"a":123, "b":234}, ""'/> --->此时key是字符串
${map['a']}
此处需要注意ognl中'×××' 如果长度是1那么是Character 否则是String 可参考
http://jinnianshilongnian.iteye.com/blog/1870662
补充:
在EL表达式规范2.2中,定义了:
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表示整数,其定义如下:
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(); } }
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(); } }
+ - * /实现,此处只看+的:
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:
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计算,其+的实现:
public static final class LongDelegate extends ELArithmetic { protected Number add(Number num0, Number num1) { return Long.valueOf(num0.longValue() + num1.longValue()); }
从这里我们可以看出其实现。
而且其规范中都规定了具体字面量的东西:
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
也规定了操作符的运算规则,如+ - *:
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型,直接交给前边介绍的IntegerLiteral。
即规范中其实已经规范了这些,但是就像java里的一些东西,虽然规范规定了(如排序时 很多人有时候使用 return a-b; 如果a是负数则可能溢出),但是还是很容易出错。
相关推荐
Java 提供了八种基本数据类型,包括四种整数类型 (byte, short, int, long),两种浮点类型 (float, double),一种字符类型 (char) 和一种布尔类型 (boolean)。 **Java变量类型** 变量是用来存储数据值的标识符。...
1. **数据类型**:MySQL支持多种数据类型,如整数(INT)、浮点数(FLOAT、DOUBLE)、字符串(VARCHAR、CHAR)、日期/时间(DATE、TIME、DATETIME)等。 2. **SQL语句**:包括SELECT用于查询数据,INSERT用于插入...
6. Java基本数据类型:包括`byte`、`short`、`int`、`long`、`float`、`double`、`boolean`和`char`。 7. 数据结构:Java中常用的数据结构有`Array`、`ArrayList`、`LinkedList`、`HashMap`和`TreeSet`等。 8. ...
- **数据类型**:Java有8种原始数据类型,分为整型(byte, short, int, long)、浮点型(float, double)、字符型(char)和布尔型(boolean)。 - **变量与常量**:理解变量的作用域、生命周期和初始化,以及常量...
Java Web开发中,Servlet是基础,JSP和EL表达式用于构建动态网页。MVC模式分离了模型、视图和控制器,Spring框架提供了全面的Web应用解决方案,Spring Boot简化了应用开发,Spring Security则提供了安全控制。...
- 基本数据类型:整型(int, short, byte, long)、浮点型(float, double)、字符型(char)、布尔型(boolean)。 - 引用数据类型:类(class)、接口(interface)、数组(array)。 2. **控制结构**: - 流程控制语句:if-...
Java Web技术包括但不限于Servlet、JSP、EL表达式、JSTL标签库、过滤器(Filter)、监听器(Listener)、Spring、Struts、Hibernate、MyBatis等流行框架。要求对MVC模式有深入理解,能够独立设计和实现Web应用。 8....
- 标记库可以通过自定义标签库(TLD)、标记文件(Tag File)或者EL表达式和JSTL实现。 4. **JSTL如何对集合进行遍历?** - 可以使用`c:forEach`标签遍历集合。 5. **JSTL如何进行条件选择?** - 可以使用`c:if...
- **JSP**:脚本元素、指令、EL表达式、JSTL标签库。 - **JDBC**:数据库连接、预编译语句、事务处理、结果集操作。 - **MVC模式**:模型-视图-控制器架构的理解和应用。 - **EJB**:Enterprise JavaBeans,包括...
18. **JSP分页**:通常通过SQL的LIMIT或OFFSET来分页,结合EL和JSTL标签库实现。 数据库方面: 1. **存储过程与函数**:存储过程可独立执行,不返回值;函数作为表达式的一部分调用,必须返回单个值。 2. **事务*...
`是EL表达式的语法,而不是用于声明变量的。 - **C**: `! char x =’中’; %>` — 正确。此语句在JSP页面的脚本元素中声明了一个成员变量`x`。 - **D**: `”中”; %>` — 错误。`<%@ ... %>` 是JSP指令的语法,...
- **表达式语言(EL)**: EL语法、隐式对象 **6. Struts2** - **Struts2架构**: MVC模式 - **Action开发**: Action类、Action拦截器 - **结果视图**: 自定义视图解析器 - **表单标签库**: 使用Struts2标签库 **7. ...
{2.8}框架中移动的小球}{59}{section.2.8} {2.9}抽象与接口}{59}{section.2.9} {2.10}访问控制}{60}{section.2.10} {2.10.1}类的属性}{60}{subsection.2.10.1} {2.10.2}类的方法}{61}{subsection.2.10.2} {...