当前位置:编程学习 > JAVA >>

探索java基本类型和包装类型的使用运算符==进行比较的底层细节

   而然某项目经理质疑的是一个包装对象和一个基本类型的值进行比较,究竟是比较值还是比较引用。而某项目经理则认为是比较引用,以下做法是错误的。但事实上是比较值,这里jdk编译后的是否对我们的对象和值的表的语句做了处理,最后都是比较基本类型的值?一下为讨论的代码,原出于hibernate的query通过unique方法取出一个Object值,实际上该值实际为Integer实例,所以使用一下类似测试代码先转换再比较的代码作为我们这次探索的问题代码。
测试比较代码:
[java] 
public class TestIntegerCompare{ 
    public static void main(String[] args) { 
        Object obj = new Integer(1024); 
        if(Integer.valueOf(obj.toString())==1024){ 
            System.out.println("bing go! Integer.valueOf(obj.toString())==1024 is true"); 
        } 
    } 
 

jdk 1.6.34 java.lang.Integer.class源码:
[java] 
public static Integer valueOf(String s, int radix) throws NumberFormatException { 
    return Integer.valueOf(parseInt(s,radix)); 

public static Integer valueOf(String s) throws NumberFormatException { 
    return Integer.valueOf(parseInt(s, 10)); 

public static Integer valueOf(int i) { 
    assert IntegerCache.high >= 127; 
    if (i >= IntegerCache.low && i <= IntegerCache.high) 
         return IntegerCache.cache[i + (-IntegerCache.low)]; 
     return new Integer(i); 

public static int parseInt(String s) throws NumberFormatException { 
    return parseInt(s,10); 

 public static int parseInt(String s, int radix) 
                throws NumberFormatException 
    {    
//省略一系列参数检测 
        int result = 0; 
        boolean negative = false; 
        int i = 0, len = s.length(); 
        int limit = -Integer.MAX_VALUE; 
        int multmin; 
        int digit; 
 
        if (len > 0) { 
            char firstChar = s.charAt(0); 
            if (firstChar < '0') { // Possible leading "+" or "-" 
                if (firstChar == '-') { 
                    negative = true; 
                    limit = Integer.MIN_VALUE; 
                } else if (firstChar != '+') 
                    throw NumberFormatException.forInputString(s); 
 
                if (len == 1) // Cannot have lone "+" or "-" 
                    throw NumberFormatException.forInputString(s); 
                i++; 
            } 
            multmin = limit / radix; 
            while (i < len) { 
                // Accumulating negatively avoids surprises near MAX_VALUE 
                digit = Character.digit(s.charAt(i++),radix); 
                if (digit < 0) { 
                    throw NumberFormatException.forInputString(s); 
                } 
                if (result < multmin) { 
                    throw NumberFormatException.forInputString(s); 
                } 
                result *= radix; 
                if (result < limit + digit) { 
                    throw NumberFormatException.forInputString(s); 
                } 
                result -= digit; 
            } 
        } else { 
            throw NumberFormatException.forInputString(s); 
        } 
        return negative ? result : -result; 
    } 
     
         让我们运行测试代码可以看到测试代码if里面的语句块是可以运行的且输出文字的,但自此我们仍对一个对象和一个基本类型的值进行比较的过程存在疑问。究竟是编译后jdk将int值转换成了Integer实例再与实例Integer实例进行比较引用,还是反之呢。这个疑问让javap帮我们看个究竟,输入javap -v -l Test TestIntegerCompare.class,可以看到以下反编译的jvm指令的呈现。


        从上述jvm指令中可以看出来,code 的标号15:确实是调用了valueOf方法解析字符串为Integer实例,但其后标号18:有调用了Integer实例的intValue()方法返回了该实例相应的int值,从而最后比较的实际是int和int进行比较,所以比较结果是true;
           通过上述分析可以确定 “包装对象==相应值” 这样的比较是可行的,但却不是推荐的。因为解析String实例为Integer实例,然后在去Integer实例里面去取的int值进行比较,在此Integer实例就多此一举了,还不如直接使用parseInt解析字符为相应的int值直接进行比较,节省创建一个Integer实例所浪费的资源。
ps:如上述解析有问题,还望各位资深

补充:软件开发 , Java ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,