最近换了份工作,公司的开发框架是基于SSH自己搭建的。这个问题是我在解决一个需求的时候遇到的,其实解决这个疑惑的过程也就是读框架源码的过程,特此记录一下。
问题:ba.getState()!=CbBankAccount.STATE_NORMAL
在二者的类型都是Integer的且字面值均为0的情况下返回了true。
我们知道Java中整型的-128~127存在JVM的运行时常量池中,当比较处于这个范围的的整型值时比较的是字面值,反之比较的是引用堆中的对象的地址。
而在我遇到的情况下二者都是0。想到可能是在某处代码调用ba.setState(Integer i)赋值时做了手脚。
接下来就是跟代码的过程了。以下代码有部分删改。
ba先从数据库查出来,再从前台请求中获取对应字段赋值。
1 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());创建了一个新的对象。故出现了上边的问题。
遇到问题还是要跟源码分析才能得到结果啊!