java中的Integer和Long值类型问题

long validDay = 1;
List<Integer> dayOfNeedHint = new ArrayList<Integer>(Arrays.asList(1,2,3,5,7));
            if(null != use_type && use_type == 2 && dayOfNeedHint.contains(valid_dd)){
            //if判断为true
}

上面的代码的条件永远也不会为true,原因为dayOfNeedHint 的contains方法会调用Integerequals 方法 ,下为Integerequals 方法源码:

public boolean equals(Object obj) {
    if (obj instanceof Integer) {
        return value == ((Integer)obj).intValue();
    }
    return false;
}

可见只要equals方法的参数类型不是IntegerInteger的子类也可以,但可惜Integerfinal类),那么就会返回false。

所以用一个Integer.equals(Long) ,永远也不会为true…

改进方法为

  1. 把dayOfNeedHint的泛型和validDay的类型进行统一
  2. 在调用List.contains(Object)的时候把validDay强转为long
  3. 对validDay调用Long.intvalue()方法
/**
 * Returns the value of this <code>Long</code> as an
 * <code>int</code>.
 */
public int intValue() {
    return (int)value;
}

注:

不要对值包装类型的变量使用 == ,因为会很危险(以Long举例):

public static void testValueType(){
        Long long1 = 20L;
        Long long2 = 20L;
        Long long3 = new Long(20L);
        Long long4 = new Long(20L);
        long long5 = 20L;
        long long6 = 20L;
        System.out.println(long1 == long2);//true  //1
        System.out.println(long1 == long3);//false //2
        System.out.println(long3 == long4);//false 
        System.out.println(long1 == long5);//true
        System.out.println(long3 == long5);//true  //3
        System.out.println(long5 == long6);//true  //4
        System.out.println("************");
        Long long12 = 2000L;
        Long long22 = 2000L;
        Long long32 = new Long(2000L);
        Long long42 = new Long(2000L);
        long long52 = 2000L;
        long long62 = 2000L;
        System.out.println(long12 == long22);//false
        System.out.println(long12 == long32);//false
        System.out.println(long32 == long42);//false
        System.out.println(long12 == long52);//true
        System.out.println(long32 == long52);//true
        System.out.println(long52 == long62);//true

        System.out.println("************");
        int i = 20;
        float f = 20.000000f;
        System.out.println(long5 == i);//true
        System.out.println(f == i);//true
        System.out.println(long1 == i);//true
    }

对于注释1,编译器自动装箱,调用jdk的Long.valueOf(20L) 因为运行时jdk会将范围为-128到127的Long类型值缓存在内存中,而valueOf方法的源码如下:

public static Long valueOf(long l) {
    final int offset = 128;
    if (l >= -128 && l <= 127) { // will cache
        return LongCache.cache[(int)l + offset];
    }
    return new Long(l);
}

会从内存的缓存中获取数据,因此long1和long2返回的时相同的引用。

对于注释2,long3由于是使用的new运算符,会在内存中新开辟一块内存,因此返回的引用肯定和jdk运行时缓存的Long对象引用不同。

而对于注释3和注释4,只要 == 运算符两侧有基本数据类型出没,那么另一侧的包装类数据类型就会自动拆箱为对应的基本类型。因此比较的总是数值。

而对于值不在-128到127的Long,编译器会调用Long.valueOf自动装箱为Long对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值