最近换了份工作,公司的开发框架是基于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. oracle查询分区表中的数据

    select * from TABLE_NAME partition(分区名) T WHERE T.COL_NAME= 'XX';

  2. avascript的匿名函数

    一.什么是匿名函数? 在Javascript定义一个函数一般有如下三种方式: 函数关键字(function)语句: function fnMethodName(x){alert(x);} 函数字面量( ...

  3. postgreSQL PL/SQL编程学习笔记(一)

    1.Structure of PL/pgSQL The structure of PL/pgSQL is like below: [ <<label>> ] [ DECLARE ...

  4. win7下钩子失效解决方案

    win7键盘钩子失效解决方法:1.win开始右键+r(运行) 2.将其输入regedit.exe(注册表管理器),回车打开注册表管理器 3.进入HKEY_LOCAL_MACHINE4.进入到SYS ...

  5. 树状数组【洛谷P3586】 [POI2015]LOG

    P3586 [POI2015]LOG 维护一个长度为n的序列,一开始都是0,支持以下两种操作:1.U k a 将序列中第k个数修改为a.2.Z c s 在这个序列上,每次选出c个正数,并将它们都减去1 ...

  6. php 镜像richarvey/nginx-php-fpm的ngnix配置

    1.遇到错误option error_page 405 =200 $request_uri; location ~ ^/(json)/ { # root /data/website/xxxx.com/ ...

  7. C# winform间窗体传值简单Demo

    form1是用来接收值的 using System; using System.Collections.Generic; using System.ComponentModel; using Syst ...

  8. nandflash之基本特性

    nandflash作为嵌入式中的”磁盘”, 被广泛的应用, 以(K9F2G08U0B)为例,其他型号都差不多 nandflash的结构 nandflash的结构有页(page), block(块)的概 ...

  9. idea 激活

    激活时选择License server,填入 http://idea.wlphp.com:1017 点击Active即可 2DZ8RPRSBU-eyJsaWNlbnNlSWQiOiIyRFo4UlBS ...

  10. Dubbo操作

    admin控制台安装 1.控制台下载地址https://github.com/apache/incubator-dubbo/releases 2.找到dubbo-admin 3.修改webapp/WE ...