• Integer的比较==和String的比较==总结


    一、序言

      今天发现了一个很有趣的问题,在群里和朋友们讨论的也比较激烈,我现在给大家阐述一下问题。

    二、发现问题

      上代码。。。

    package com.hzwealth.test.question;
    
    public class IntegerTest {
        public static void main(String[] args) {
            //Integer
            Integer a=10,b=10,c=150,d=150;
            System.out.println(a==b);   
            System.out.println(c==d);
            System.out.println(a.equals(b));
            System.out.println(c.equals(d));
            //String
            String str=new String("AB");
            String str1 ="A";
            String str2 = str1+"B";
            String str3="AB";
            System.out.println(str==str3);
            System.out.println(str==str2);
            System.out.println(str2==str3);
        }
    }

    三、解决问题

      1、Integer的问题,首先我们先看上面代码的 a==b会输出什么呢,答案是true,这个毋庸置疑,但是c==d会输出什么呢,答案是false,为什么呢?

        (1)Integer是基本数据类型的int的引用类型,官方语言叫做装箱类型,我们来看一下Integer的源码

    //Integer的取值
    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);
        }
    
    private static class IntegerCache {
            static final int low = -128;
            static final int high;
            static final Integer cache[];
    
            static {
                // high value may be configured by property
                int h = 127;
                String integerCacheHighPropValue =
                    sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
                if (integerCacheHighPropValue != null) {
                    int i = parseInt(integerCacheHighPropValue);
                    i = Math.max(i, 127);
                    // Maximum array size is Integer.MAX_VALUE
                    h = Math.min(i, Integer.MAX_VALUE - (-low));
                }
                high = h;
    
                cache = new Integer[(high - low) + 1];
                int j = low;
                for(int k = 0; k < cache.length; k++)
                    cache[k] = new Integer(j++);
            }
    
            private IntegerCache() {}
        }

      从源码我们可以看出,Integer的值为-128-127之间的时候就会自动的从Integer的缓存(IntegerCache)中去取,如果超过这个范围就会新建一个Integer的对象。

      所以a==b(a=10,b=10)为true,c==d(c=150,d=150)为false。

     2、我们来看一下String的这个问题

      (1)str==str3 为false,因为,str新建了一个对象,str3是常量池中的对象,所以这两个为false。

      (2)str2==str3,这个解释引用我群友  成都-119-EbranHan-Java 的解释:

       new 了一个 StringBuilder,然后调用了append方法,对应的就是:String str2 = str1+"B";

      这里还提到了字面量和引用,String str3="AB",这就是字面量,而引用就是,String str=new String("AB");我们自己定义的。

       字面量 jvm 优化过,直接就扔到常量池去了。

      下面是StringBuilder的toString方法,这里也是新建了一个String方法

     

        综上所述,str2==str3也为false。

      补充:这里的“+”不是用的String 的concat的方法,而是用的是StringBuilder来写的。而且,就算是用concat的方法也是new了一个String的对象。下面是concat的源码:

    public String concat(String str) {
            int otherLen = str.length();
            if (otherLen == 0) {
                return this;
            }
            int len = value.length;
            char buf[] = Arrays.copyOf(value, len + otherLen);
            str.getChars(buf, len);
            return new String(buf, true);
        }

      (3)str==str2,这个也毋庸置疑的为false了,因为str是new出来的String对象,str2也是相当于new出来的一个对象。所以为false。

    四、评语

      以上是我根据自己查阅资料以及和群友的交流下写出的总结,如果有不正确的地方,还望大牛指正!

  • 相关阅读:
    2019第二周作业
    求最大值及其下标
    查找整数
    2018秋季学习总结
    抓老鼠 亏了还是赚了
    币值转换
    打印沙漏
    从文本中找出url,并附上链接。
    手机端点击输入框页面会放大
    <dl>、<dt>和<dd>标记的用法
  • 原文地址:https://www.cnblogs.com/lixiaochao/p/6527147.html
Copyright © 2020-2023  润新知