Java 中“==”和equals(Object obj);

1. ==操作符:

        == 比较的是 变量(栈)内存中存放的对象的(堆)内存地址,用来 判断两个对象的地址是否相同,即 是否是指相同一个对象。比较的是真正意义上的指针操作。
        a、比较的是操作符两端的操作数 是否是同一个对象
        b、两边的操作数必须是 同一类型的(可以是父子类之间)才能编译通过。
        c、比较的是地址,如果是具体的阿拉伯数字的比较, 值相等则为true,如:
        int a=10 与 long b=10L 与 double c=10.0都是相同的(为true),因为他们都指向地址为10的堆。

2. 对equals分析源码有:

     a. 在Object中有:

public boolean equals(Object obj) {
        return (this == obj);
    }

      b. 在String中有:

 public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String)anObject;
            int n = value.length;                           //字符串长度
            if (n == anotherString.value.length) {
                char v1[] = value;                          //String 中使用private final char value[];存储字符串
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }

      可以看出,不论是Object.equals( )或者Srting.equals( )中,方法参数都是一个obj,即对象,此时有equals不能用于基本数据类型的判断。

     c.  对包装类,以Integer为例,有:

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

      可以看出,实际上,Object和Integer实际上仍是值的比较(基本数据类型是否是同一对象),而String 的equals不仅仅含有值的比较(是否是同一对象),还有字符串内容(两个字符串内容是否相同(仅限同一类型的(可以是父子类之间)))的比较。

3. 特殊情形:(String s="abce";和String s = new String("abcd");)

    String s="abce"是一种非常特殊的形式,和new 有本质的区别。它是java中唯一不需要new 就可以产生对象的途径。以String s="abce";形式赋值在java中叫直接量,它是在常量池中而不是像new一样放在堆中。这种形式的字符串,在JVM内部发生字符串拘留,即当声明这样的一个字符串后,JVM会在常量池中先查找有有没有一个值为"abcd"的对象,如果有,就会把它赋给当前引用。即原来那个引用和现在这个引用指点向了同一对象,如果没有,则在常量池中新创建一个"abcd",下一次如果有String s1 = "abcd";又会将s1指向"abcd"这个对象,即以这形式声明的字符串,只要值相等,任何多个引用都指向同一对象。

String s1 = "chance";
String s2 = "chance";
System.out.println(s1 == s2);        //true
System.out.println(s1.equals(s2));    //true


 而String s = new String("abcd"); 和其它任何对象一样,每调用一次就产生一个对象,只要它们调用。

String s3 = new String("chance");     
String s4 = new String("chance");
System.out.println(s3 == s4);        //false
System.out.println(s3.equals(s4));    //true
     可见在非String类中, ==和equals的作用都是一样的,只不过在String类中重写了equals方法,才会变得这么复杂!!!!

4. int与Integer:

        Java的8种基本类型(Byte, Short, Integer, Long, Character, Boolean, Float, Double), 除Float和Double以外, 其它六种都实现了常量池, 但是它们只在大于等于-128并且小于等于127时才使用常量池。

       a. 两个通过new生成的Integer变量永远是不相等的:

      Integer i = new Integer(100);
      Integer j = new Integer(100);
      System.out.print(i == j); //false

         因为new生成的是两个对象,其内存地址不同。

        b. Integer变量和int变量比较时,只要两个变量的值是向等的,则结果为true:

    Integer i = new Integer(100);
    int j = 100;
    System.out.print(i == j);    //true

           因为包装类Integer和基本数据类型int比较时,java会自动拆包装为int,然后进行比较,实际上就变为两个int变量的比较

        c. 对于两个非new生成的Integer对象(存在常量池中),进行比较时,如果两个变量的值在区间-128到127之间,则比较结果为true,如果两个变量的值不在此区间,则比较结果为false

     Integer i = 100;
     Integer j = 100;
     System.out.print(i == j); //true

     Integer i = 128;
     Integer j = 128;
     System.out.print(i == j); //false

         java在编译Integer i = 100 ;时,会翻译成为Integer i = Integer.valueOf(100)。而java API中对Integer类型的valueOf的定义如下,对于-128到127之间的数,会进行缓存,Integer i = 127时,会将127进行缓存,下次再写Integer j = 127时,就会直接从缓存中取,就不会new了。

         d. 非new生成的Integer变量和new Integer()生成的变量比较时,结果为false。

      Integer i = new Integer(100);
      Integer j = 100;
      System.out.print(i == j); //false

        因为非new生成的Integer变量指向的是java常量池中的对象(-128到127之间,而new Integer()生成的变量指向堆中新建的对象,两者在内存中的地址不同。




参考博客:

    1. https://www.cnblogs.com/Eason-S/p/5524837.html

    2. https://blog.csdn.net/chance2015/article/details/51427304

    3. https://blog.csdn.net/chenliguan/article/details/53888018

    4. https://blog.csdn.net/shw2004/article/details/5678703

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值