(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 ...
随机推荐
- Swoole http server + yaf, swoole socket server + protobuf 等小结
拥抱swoole, 拥抱更好的php Swoole 是什么? Yaf 是什么? 接触swoole已经4年多了,一直没有好好静下心来学习.一直在做web端的应用,对网络协议和常驻内存型服务器一窍不通.一 ...
- 在虚拟机中连接oracle数据库报错ORA-12154,其他服务器连接无问题
在一台服务器上使用sqlplus登录oracle数据库,cmd->sqlplus->name/passwd@orcl2登录某个数据库用户,提示ORA-12154.使用当前服务器的PLSQL ...
- loj #2509. 「AHOI / HNOI2018」排列
#2509. 「AHOI / HNOI2018」排列 题目描述 给定 nnn 个整数 a1,a2,…,an(0≤ai≤n),以及 nnn 个整数 w1,w2,…,wn.称 a1,a2,…,an 的 ...
- CAP理论中的P到底是个什么意思
在CAP理论中,C代表一致性,A代表可用性(在一定时间内,用户的请求都会得到应答),P代表分区容错.这里分区容错到底是指数据上的多个备份还是说其它的 ? 我感觉分布式系统中,CAP理论应该是C和A存在 ...
- 条目八《永不建立auto_ptr的容器》
条目八<永不建立auto_ptr的容器> 重要的事说三次,永不建立auto_ptr的容器,永不建立auto_ptr的容器,永不建立auto_ptr的容器!!! 为什么? 实质是auto_p ...
- 百度分享,简单的一步操作解决你的网站不支持https访问的问题!
百度分享,应该是目前最好用的前端分享插件了.然而,官方却没有支持https.现在越来越多的网站都走入https的安全加密队列了,那么在找不到更好地替代品的情况下,怎么能让它支持https呢? 答案当然 ...
- audio.play dom对象 JQ不支持play
*/ PausePlayVoice:function() { $("#spPauseAudio").click(function() { ...
- IntelliJ IDEA 把Maven项目导出可执行jar包
2017年04月05日 14:05:08 waterimelon 阅读数:1574 标签: intellij ideamaven 更多 个人分类: idea 第一步 第二步 第三步
- 原生JS实现返回顶部和滚动锚点
;(function (window,doc,undefined) { function rollingAnchor(){ this.timer =''; } rollingAnchor.protot ...
- IIS环境下上传文件失败
跟随学习代码练习 php 上传文件,一开始是点击按钮后没有反应,不知道是否成功,使用 var_dump($_FILES) 查看,发现空空如也.遂百度一下,发现基本代码应如下 <form acti ...