最近换了份工作,公司的开发框架是基于SSH自己搭建的。这个问题是我在解决一个需求的时候遇到的,其实解决这个疑惑的过程也就是读框架源码的过程,特此记录一下。

问题:ba.getState()!=CbBankAccount.STATE_NORMAL

在二者的类型都是Integer的且字面值均为0的情况下返回了true。

我们知道Java中整型的-128~127存在JVM的运行时常量池中,当比较处于这个范围的的整型值时比较的是字面值,反之比较的是引用堆中的对象的地址。

而在我遇到的情况下二者都是0。想到可能是在某处代码调用ba.setState(Integer i)赋值时做了手脚。

接下来就是跟代码的过程了。以下代码有部分删改。

ba先从数据库查出来,再从前台请求中获取对应字段赋值。

 ba = (CbBankAccount) super.getBeanForUpdate(CbBankAccount.class, ba);
public <T> T getBeanForUpdate(Class<T> clazz, Object obj) {
Assert.notNull(obj);
Assert.notNull(clazz);
return HttpUtils.getBean(getRequest(), clazz, obj);
}
public static <T> T getBean(HttpServletRequest request, Class<T> c,
Object obj) {
Map<String, Object> paramMap = request.getParameterMap();
Object value = null;
Class[] paramTypes = new Class[1]; try {
Field[] f = c.getDeclaredFields();
List<Field[]> flist = new ArrayList<Field[]>();
flist.add(f);
Class superClazz = c.getSuperclass(); // 获取父类,如果父类存在则取父类的Field
while (superClazz != null) {
f = superClazz.getDeclaredFields();
flist.add(f);
superClazz = superClazz.getSuperclass();
}
for (Field[] temp : flist) {
for (Field field : temp) {
String fName = field.getName(); value = paramMap.get(fName);
if (value != null) {
paramTypes[0] = field.getType();
Method method = null;
StringBuffer methodName = new StringBuffer("set");
methodName.append(fName.substring(0, 1).toUpperCase());
methodName.append(fName.substring(1, fName.length()));
method = c.getMethod(methodName.toString(), paramTypes);
method.invoke(obj, getValue(request, fName,
paramTypes[0]));//从请求中获得字段对应值并赋值
} }
}
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} return (T) obj;
}

....

最终在转换数字的地方找到了答案(使用的是org.apache.commons.beanutils.converters.NumberConverter)

private Number toNumber(Class sourceType, Class targetType, Number value) {

        // Correct Number type already
if (targetType.equals(value.getClass())) {
return value;
} // Byte
if (targetType.equals(Byte.class)) {
long longValue = value.longValue();
if (longValue > Byte.MAX_VALUE) {
throw new ConversionException(toString(sourceType) + " value '" + value
+ "' is too large for " + toString(targetType));
}
if (longValue < Byte.MIN_VALUE) {
throw new ConversionException(toString(sourceType) + " value '" + value
+ "' is too small " + toString(targetType));
}
return new Byte(value.byteValue());
} // Short
if (targetType.equals(Short.class)) {
long longValue = value.longValue();
if (longValue > Short.MAX_VALUE) {
throw new ConversionException(toString(sourceType) + " value '" + value
+ "' is too large for " + toString(targetType));
}
if (longValue < Short.MIN_VALUE) {
throw new ConversionException(toString(sourceType) + " value '" + value
+ "' is too small " + toString(targetType));
}
return new Short(value.shortValue());
} // Integer
if (targetType.equals(Integer.class)) {
long longValue = value.longValue();
if (longValue > Integer.MAX_VALUE) {
throw new ConversionException(toString(sourceType) + " value '" + value
+ "' is too large for " + toString(targetType));
}
if (longValue < Integer.MIN_VALUE) {
throw new ConversionException(toString(sourceType) + " value '" + value
+ "' is too small " + toString(targetType));
}
return new Integer(value.intValue());
} // Long
if (targetType.equals(Long.class)) {
return new Long(value.longValue());
} // Float
if (targetType.equals(Float.class)) {
if (value.doubleValue() > Float.MAX_VALUE) {
throw new ConversionException(toString(sourceType) + " value '" + value
+ "' is too large for " + toString(targetType));
}
return new Float(value.floatValue());
} // Double
if (targetType.equals(Double.class)) {
return new Double(value.doubleValue());
} // BigDecimal
if (targetType.equals(BigDecimal.class)) {
if (value instanceof Float || value instanceof Double) {
return new BigDecimal(value.toString());
} else if (value instanceof BigInteger) {
return new BigDecimal((BigInteger)value);
} else {
return BigDecimal.valueOf(value.longValue());
}
} // BigInteger
if (targetType.equals(BigInteger.class)) {
if (value instanceof BigDecimal) {
return ((BigDecimal)value).toBigInteger();
} else {
return BigInteger.valueOf(value.longValue());
}
} String msg = toString(getClass()) + " cannot handle conversion to '"
+ toString(targetType) + "'";
if (log().isWarnEnabled()) {
log().warn(" " + msg);
}
throw new ConversionException(msg); }

return new Integer(value.intValue());创建了一个新的对象。故出现了上边的问题。

遇到问题还是要跟源码分析才能得到结果啊!

(0!=0)==true? 记一个匪夷所思的问题的更多相关文章

  1. console.log(0.2+0.4===0.6)// true or false??

    在正常的数学逻辑思维中,0.2+0.4===0.6这个逻辑是正确的,但是在JavaScript中0.2+0.4!==0.6这是为什么呢?这个问题也会偶尔被用来当做面试题来考查面试者对 JavaScri ...

  2. 从 0 开始手写一个 Mybatis 框架,三步搞定!

    阅读本文大概需要 3 分钟. MyBatis框架的核心功能其实不难,无非就是动态代理和jdbc的操作,难的是写出来可扩展,高内聚,低耦合的规范的代码. 本文完成的Mybatis功能比较简单,代码还有许 ...

  3. 未能加载文件或程序集“Microsoft.ReportViewer.WebForms, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a”或它的某一个依赖项。系统找不到指定的文件

    发布的打包项目在本机测试好使,部署到客户服务器上报错 分析器错误消息: 未能加载文件或程序集“Microsoft.ReportViewer.WebForms, Version=10.0.0.0, Cu ...

  4. 用Scratch2.0源码定制一个自己的编辑器

    用Scratch2.0源码定制一个自己的编辑器,换成自己的软件名称和图标,添加中文字体,修复汉化错误等等1.准备:下载Scratch2.0源码.安装开发工具Adobe Flash Builder4.7 ...

  5. Oracle 远程访问配置 在 Windows Forms 和 WPF 应用中使用 FontAwesome 图标 C#反序列化XML异常:在 XML文档(0, 0)中有一个错误“缺少根元素” C#[Win32&WinCE&WM]应用程序只能运行一个实例:MutexHelper Decimal类型截取保留N位小数向上取, Decimal类型截取保留N位小数并且不进行四舍五入操作

    Oracle 远程访问配置   服务端配置 如果不想自己写,可以通过 Net Manager 来配置. 以下配置文件中的 localhost 改为 ip 地址,否则,远程不能访问. 1.网络监听配置 ...

  6. LinkedHashMap<String, Bitmap>(0, 0.75f, true) LinkedHashMap的加载因子和初始容量分配

    今天上午在CSDN的论坛里看到有朋友提的问题如下: /** @param maxSize Maximum sum of the sizes of the Bitmaps in this cache * ...

  7. Go语言之从0到1实现一个简单的Redis连接池

    Go语言之从0到1实现一个简单的Redis连接池 前言 最近学习了一些Go语言开发相关内容,但是苦于手头没有可以练手的项目,学的时候理解不清楚,学过容易忘. 结合之前组内分享时学到的Redis相关知识 ...

  8. 使用react+redux+react-redux+react-router+axios+scss技术栈从0到1开发一个applist应用

    先看效果图 github地址 github仓库 在线访问 初始化项目 #创建项目 create-react-app applist #如果没有安装create-react-app的话,先安装 npm ...

  9. 从0到1发布一个npm包

    从0到1发布一个npm包 author: @TiffanysBear 最近在项目业务中有遇到一些问题,一些通用的方法或者封装的模块在PC.WAP甚至是APP中都需要使用,但是对于业务的PC.WAP.A ...

随机推荐

  1. 【ARC080F】Prime Flip 差分+二分图匹配

    Description ​ 有无穷个硬币,初始有n个正面向上,其余均正面向下.  你每次可以选择一个奇质数p,并将连续p个硬币都翻转.  问最小操作次数使得所有硬币均正面向下. Input ​ 第一行 ...

  2. Nagios监控平台搭建及配置文件详解

    Nagios是一款开源的免费网络监视工具,能有效监控Windows.Linux和Unix的主机状态,交换机路由器等网络设置,打印机等.在系统或服务状态异常时发出邮件或短信报警第一时间通知网站运维人员, ...

  3. ios网络 -- HTTP请求 and 文件下载/断点下载

    一:请求 http://www.jianshu.com/p/8a90aa6bad6b 二:下载 iOS网络--『文件下载.断点下载』的实现(一):NSURLConnection http://www. ...

  4. rabbitmq生产者代码,以及过程参数含义:

    首先pom依赖: <?xml version="1.0" encoding="UTF-8"?> <project xmlns="ht ...

  5. DEM反应不收敛问题

    之前算DEM反应一直不收敛,后来把计算规模减少到两个固定颗粒,也就是仿照reactive-chemistry和evaperation这两个算例. 目前reactive-chemistry这个算例,把各 ...

  6. poj2420 A Star not a Tree? 找费马点 模拟退火

    题目传送门 题目大意: 给出100个二维平面上的点,让你找到一个新的点,使这个点到其他所有点的距离总和最小. 思路: 模拟退火模板题,我也不懂为什么,而且一个很有意思的点,就是初始点如果是按照我的代码 ...

  7. AMD、CMD/AMD与CMD的区别

    http://blog.csdn.net/jackwen110200/article/details/52105493

  8. VBS添加Windows登陆账号

    Set o=CreateObject( "Shell.Users" ) Set z=o.create("test") z.changePassword &quo ...

  9. os.path模块

    什么是os.path模块 该模块用于处理路径,我们知道python是一门跨平台的语言,二每种操作系统,文件路径是截然不同的,为了使程序可以在不同平台生正确运行,python提供了该模块,使用该模块可以 ...

  10. PIE SDK频率域滤波

    1.算法功能简介 频率域滤波的基本工作流程为:空间域图像的傅里叶变换→频率域图像→设计滤波器→傅里叶逆变换→其他应用. 低通滤波,对频率域的图像通过滤波器削弱或抑制高频部分而保留低频部分的滤波方法,可 ...