==对比的是栈中的值,是判断两个变量或者实例是不是指向同一个内存空间

而equals是判断两个变量或者实例指向同一个内存空间的值是不是相同

object中equals中默认也是采用==,通常会重写

object:

Java面试题(三):==和equals比较

String:

Java面试题(三):==和equals比较

从上面代码可以看出,String类中被复写的equals()方法其实是比较两个字符串的内容。

public class StringDemo {
    public static void main(String[] args) {
        String str1 = "Hello";
        String str2 = new String("Hello");
        String str3 = str2; //引用传递
        
        System.out.println(str1 == str2); //false
        System.out.println(str1 == str3); //false
        System.out.println(str2 == str3); //true
        System.out.println(str1.equals(str2)); //true
        System.out.println(str1.equals(str3)); //true
        System.out.println(str2.equals(str3)); //true
    }
}

str1 == str2,因为new String("Hello")是重新开辟了一个地址,和str1地址不同,所以结果为false。

基本数据类型存放位置有所改动:

JDK1.6及以前,常量池在方法区,这时的方法区也叫做永久代;
JDK1.7的时候,方法区合并到了堆内存中,这时的常量池也可以说是在堆内存中;
JDK1.8及以后,方法区又从堆内存中剥离出来了,但实现方式与之前的永久代不同,这时的方法区被叫做元空间,常量池就存储在元空间。

 

 

 

public static void main(String[] args){
//这里使用常量池存在的字符串,构建字符串对象

String s = new String("1");

s.intern();

String s2 = "1";

System.out.println(s == s2);

//这里构建一个常量池不存在的字符串对象

String s3 = new String("1") + new String("1");

s3.intern();

String s4 = "11";

System.out.println(s3 == s4);

}

 

 

代码解释:

s与s1的目的是为了比较:当常量池存在这个值时,new方法产生的字符串 与 intern后再使用常量产生的字符串是否为一个对象。

s3与s4的目的是为了比较:当常量池不存在这个值时,new方法产生的字符串 与 intern后再使用常量产生的字符串是否为一个对象。

如果你有两个JDK环境:1.6与1.7

你会得到两个截然不同的答案:

JDK1.6: false false

JDK1.7: false true

然后了解一下JDK1.6与JDK1.7中常量池的区别

先看看JDK1.6

在JDK1.6中,常量池是一块独立的区域,jdk6中的常量池是放在 Perm 区中的,Perm 区和正常的 JAVA Heap 区域是完全分开的。

有点人可能不是很懂

这里再换种说法:

“String”类型的String,存放在常量池,同时常量池与Java堆是两个不同的部分。

也就是说,

存放在常量池和存放在堆,实现方式都不一样。

常量池默认4M,所以存在消耗尽,抛出java.lang.OutOfMemoryError: PermGen space

调用intern方法,字符串若不存在在常量池,则会在方法区新建一个并返回

Java面试题(三):==和equals比较

 

 

 

在JDK1.7中,取消了这个称为perm的区域,常量池就是堆,在常量池中的String对象和堆的String对象是存在与同一区域的。

在 jdk7 的版本中,字符串常量池已经从 Perm 区移到正常的 Java Heap 区域了。

为什么要移动,Perm 区域太小是一个主要原因,当然据消息称 jdk8 已经直接取消了 Perm 区域,而新建立了一个元区域。应该是 jdk 开发者认为 Perm 区域已经不适合现在 JAVA 的发展了。

也就是说:JDK1.7中,常量池被放在了堆中,于是我们再次调用一个 常量池不存在的字符串的intern方法,就不需要新建对象了。

Java面试题(三):==和equals比较

 

 总结:JDK1.7中,字符串的位置从方法区调整到了堆,执行intern时,若没有这个字符,将把当前的字符串放进常量池,而不是新建一个

 

相关文章:

  • 2021-12-30
  • 2021-11-21
  • 2022-12-23
  • 2022-12-23
  • 2022-02-22
  • 2022-02-04
  • 2021-06-03
  • 2022-12-23
猜你喜欢
  • 2021-07-01
  • 2021-08-15
  • 2021-11-28
  • 2021-07-15
  • 2021-12-29
  • 2021-09-28
  • 2022-02-15
相关资源
相似解决方案