• (0!=0)==true? 记一个匪夷所思的问题


    最近换了份工作,公司的开发框架是基于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;
        }
    View Code

    ....

    最终在转换数字的地方找到了答案(使用的是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);
    
        }
    View Code

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

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

  • 相关阅读:
    杂题之求1-100连续不重复整数中的缺少的一个数
    C语言之位运算
    程序员的激情其实是一种痛苦
    主机windwo7+虚拟机centos如何配置虚拟机可以上网,且与主机互ping通
    MyEclipse Servers视窗出现“Could not create the view: An unexpected exception was thrown”错误解决办法
    一个web项目在myeclipse中add deployment时无法被识别出来的原因
    Hibernate中,将session绑定到线程时,在保存和查询数据的代码里,要正确的关闭session
    springframwork历史版本下载地址
    在web项目中使用cxf开发webservice,包含spring支持
    [转] Spring Security(01)——初体验
  • 原文地址:https://www.cnblogs.com/xushy/p/9365421.html
Copyright © 2020-2023  润新知