(0!=0)==true? 记一个匪夷所思的问题
最近换了份工作,公司的开发框架是基于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? 记一个匪夷所思的问题的更多相关文章
- 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 ...
- 从 0 开始手写一个 Mybatis 框架,三步搞定!
阅读本文大概需要 3 分钟. MyBatis框架的核心功能其实不难,无非就是动态代理和jdbc的操作,难的是写出来可扩展,高内聚,低耦合的规范的代码. 本文完成的Mybatis功能比较简单,代码还有许 ...
- 未能加载文件或程序集“Microsoft.ReportViewer.WebForms, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a”或它的某一个依赖项。系统找不到指定的文件
发布的打包项目在本机测试好使,部署到客户服务器上报错 分析器错误消息: 未能加载文件或程序集“Microsoft.ReportViewer.WebForms, Version=10.0.0.0, Cu ...
- 用Scratch2.0源码定制一个自己的编辑器
用Scratch2.0源码定制一个自己的编辑器,换成自己的软件名称和图标,添加中文字体,修复汉化错误等等1.准备:下载Scratch2.0源码.安装开发工具Adobe Flash Builder4.7 ...
- 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.网络监听配置 ...
- LinkedHashMap<String, Bitmap>(0, 0.75f, true) LinkedHashMap的加载因子和初始容量分配
今天上午在CSDN的论坛里看到有朋友提的问题如下: /** @param maxSize Maximum sum of the sizes of the Bitmaps in this cache * ...
- Go语言之从0到1实现一个简单的Redis连接池
Go语言之从0到1实现一个简单的Redis连接池 前言 最近学习了一些Go语言开发相关内容,但是苦于手头没有可以练手的项目,学的时候理解不清楚,学过容易忘. 结合之前组内分享时学到的Redis相关知识 ...
- 使用react+redux+react-redux+react-router+axios+scss技术栈从0到1开发一个applist应用
先看效果图 github地址 github仓库 在线访问 初始化项目 #创建项目 create-react-app applist #如果没有安装create-react-app的话,先安装 npm ...
- 从0到1发布一个npm包
从0到1发布一个npm包 author: @TiffanysBear 最近在项目业务中有遇到一些问题,一些通用的方法或者封装的模块在PC.WAP甚至是APP中都需要使用,但是对于业务的PC.WAP.A ...
随机推荐
- Ubuntu 安装后的配置及美化(一)
Ubuntu 安装后的配置及美化(一) 记录一下 完成后的主界面. 配置 1.更新源为阿里云 找到 软件和更新 选项,更新源为阿里云的源. 在 其他软件 中将 Canonical合作伙伴 打上勾. 然 ...
- bzoj2395 [Balkan 2011]Timeismoney(最小乘积生成树+计算几何)
题意 每条边有两个权值\(c,t\),请求出一颗生成树,使得\(\sum c\times \sum t\)最小 题解 为什么生成树会和计算几何扯上关系-- 对于每棵树,设\(x=c,y=t\),我们可 ...
- LVS解决高并发,大数据量
http://www.360doc.com/content/14/0726/00/11962419_397102114.shtml LVS的全称Linux vitual system,是由目前阿里巴巴 ...
- 《Andrew Ng深度学习》笔记2
神经网络基础 1.图计算 计算时有两种方法:正向传播和反向传播.正向传播是从底层到顶层的计算过程,逐步推出所求公式.反向传播是从顶层到底层,从已知的式子求出因变量的影响关系. 在这里用到的反向传播算法 ...
- 导出table为Excel
1.HTML <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset=" ...
- APUE第八章-进程控制
一.进程标识 二.函数fork 1.写时复制,copy-on-write 2.文件共享,父进程等待子进程完成,子进程结束后,它对任一共享描述符的读写操作的文件偏移量已做相应的更新,同时操作时,可以考虑 ...
- sql update 代替游标写法
update TB_AreaUserDevice_Relation set OrderID = t.r from TB_AreaUserDevice_Relation rel inner join ( ...
- sql 语句设置主键
创建表时候 SQL code? 1 2 3 4 CREATE TABLE tb ( id INT IDENTITY(1,1) PRIMARY KEY, ) 添加时候 SQL code? 1 2 ALT ...
- BAM/SAM格式
本质上就是二进制压缩的SAM文件,大部分生物信息学流程都需要这个格式,为了节省存储空间以及方便索引. # BiocInstaller::biocLite('Rsamtools') library(Rs ...
- 关于Manjaro与Ubuntu双系统并存引发的一个boot问题
事情发生在写下这篇博客的半小时前.笔者的电脑本身是Manjaro+win10双系统并存,因为一些原因要安装ubuntu. 装完ubuntu用了一阵子,想切回manjaro,于是遇到了这个问题. 看到k ...