Java中的==和equals

Java堆栈

Java把内存划分为两种:一种是栈内存,一种是堆内存。

基本数据类型的变量和对象的引用变量都在函数的栈内存中分配。

堆内存用来存放new创建的对象和数组

Java数据类型

1、基本数据类型

  数值型:byte  short  int  long  float  double

  字符型:  char

  布尔型:boolean

他们之间的比较,使用==,比较的是他们的值。

2、引用数据类型

  数组  类   接口

当他们用==进行比较的时候,比较的是他们堆内存中存放的地址,所以同一个new出来的对象,比较后结果是true,否则是false

JAVA当中所有的类都是继承Object这个父类的,Object类中定义了一个equals方法,这个方法的实现实质上还是比较对象的在堆中的内存地址,也有一些类对这个方法进行了覆盖,例如String类,这些类中equals有其自身的实现,所以不再是比较堆内存中的存放地址了。

Object类中的equals实现:

 

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

 

String类中equals实现:

 

public boolean equals(Object anObject) {
 if (this == anObject) {
     return true;
 }
 if (anObject instanceof String) {
     String anotherString = (String)anObject;
     int n = count;
     if (n == anotherString.count) {
     char v1[] = value;
     char v2[] = anotherString.value;
     int i = offset;
     int j = anotherString.offset;
     while (n-- != 0) {
      if (v1[i++] != v2[j++])
          return false;
     }
          return true;
     }
 }
     return false;
  }

 

代码示例:

package com.fwj.teststring;

public class TestString {

    public static void main(String[] args) {

        String str1 = "hello world";
        String str2 = "hello world";
        if(str1==str2)
            System.out.println("str1==str2");
        else
            System.out.println("str1!=str2");
    }

}

运行结果:

str1==str2

这是由于str1和str2引用了同一个String对象

再看下边示例:

package com.fwj.teststring;

public class TestString {

    public static void main(String[] args) {

        String str1 = "hello world";
        String str2 = new String(str1);
        
        if(str1==str2)
            System.out.println("str1==str2");
        else
            System.out.println("str1!=str2");
        if(str1.equals(str2))
            System.out.println("str1 equals str2");
        else
            System.out.println("str1 not equals str2");
    }

}

运行结果:

str1!=str2
str1 equals str2

这是由于str1和str2引用了两个”hello world”对象

字符串缓冲池

程序运行的时候会创建一个字符串缓冲池,当使用str2=hello world创建字符串的时候,程序首先会在字符串缓冲池中寻找相同值对象。第一个程序中,str1先被放到了缓冲池中。所以str2被创建的时候,程序找到了具有相同值的str1,将str1的引用指向了str2

第二段程序中,使用了new操作符,明白的告诉程序:“我要一个新的对象”于是创建了一个新的hello world对象,他们的值相同,但位置不同。

第三段程序:

 1 package com.fwj.teststring;
 2 
 3 public class TestString {
 4 
 5     public static void main(String[] args) {
 6 
 7         String str1 = "hello world";
 8         String str2 = new String(str1);
 9         str2 = str2.intern();
10         if(str1==str2)
11             System.out.println("str1==str2");
12         else
13             System.out.println("str1!=str2");
14         if(str1.equals(str2))
15             System.out.println("str1 equals str2");
16         else
17             System.out.println("str1 not equals str2");
18     }
19 
20 }

运行结果:

str1==str2
str1 equals str2

这是由于Stringintern()方法的返回值仍然是字符串,intern()方法检查字符串池里是否存在hello world这么一个字符串,如果存在,就返回字符串池里的字符串,如果不存在,该方法会把hello world添加到字符串缓冲池里,然后再返回它的引用。

 

 

原文地址:https://www.cnblogs.com/mingluosunshan/p/3231865.html