zoukankan      html  css  js  c++  java
  • (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());创建了一个新的对象。故出现了上边的问题。

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

  • 相关阅读:
    扫面线模板
    (动态规划、栈)leetcode 84. Largest Rectangle in Histogram, 85. Maximal Rectangle
    tmux 常见命令汇总
    leetcode 221
    leetcode 319 29
    (贪心)leetcode 392. Is Subsequence, 771. Jewels and Stones, 463. Island Perimeter
    leetcode 982 668
    Python import 同文件夹下的py文件的函数,pycharm报错
    Windows里Anaconda-Navigator无法打开的解决方案
    Windows下 gpu版 Tensorflow 安装
  • 原文地址:https://www.cnblogs.com/xushy/p/9365421.html
Copyright © 2011-2022 走看看