Java基础Android进阶之路Android开发

【Java】Java中的==

2019-07-14  本文已影响57人  秀叶寒冬

Java中的==

Java中的==表示的是什么呢?有时候很令人费解。比如,以下例子输出是什么?

        // 例一
        String str = "wo";
        String str1 = "wo";
        System.out.println("例一:" + (str == str1));

        // 例二
        String str2 = new String("wo");
        String str3 = new String("wo");
        System.out.println("例二:" + (str2 == str3));

        // 例三
        int i1 = 1;
        int i2 = 1;
        System.out.println("例三:" + (i1 == i2));

        // 例四
        TestObject t1 = new TestObject();
        TestObject t2 = new TestObject();
        System.out.println("例四:" + (t1 == t2));

其中,TestObject是自定义的一个类,结构如下:

package com.yds.test;

public class TestObject {
    public TestObject(){
        
    }
}

最终的结果输出什么呢?结果如下:

例一:true
例二:false
例三:true
例四:false

其实,在Java中,如果是基本数据类型,则 == 比较的是值;如果是对象类型,则 == 比较的是对象的地址。但是,有时候会疑惑,String不是对象类型么?为什么例一是true呢?这个就要谈谈字符串常量池的问题。

2 字符串常量池

String类是我们平常项目中使用频率非常高的一种对象类型,JVM为了提升性能和减少开销,避免字符串的重复创建,维护了一块特殊的内存空间,即字符串常量池。当需要使用字符串时,先去字符串常量池查看该字符串是否已经存在,如果存在,则可直接使用;如果不存在,初始化,并将该字符串放入到字符串常量池中。

  • 在JDK1.6及之前版本,字符串常量池在方法区中
  • 在JDK1.7及以后版本,字符串常量池移到了堆中

使用String str="wo",可能创建一个或者不创建对象。如果“wo”在字符串常量池中已经存在,则不会再创建String类型的值为“wo”的对象,而是将str指向这个“wo”对象内存地址,后续无论用这种方式创建多少个指向“wo”的引用,在内存中,都只有一个“wo”内存地址被分配。而==判断的是对象内存的地址,所以例一返回true。下图是用这种方式创建字符串的示例图。


例一示例图
  • 对象存放在堆中,字符串常量池是堆中一块特殊区域,new出来的是对象,字符串可以通过直接赋值创建一个对象,如上所述。
  • 对象的引用存放在栈中,String str是对象的引用

在上图中,栈存放的是字符串的引用,str和str1存放的都是对象“wo”的内存地址,==判断对象时,判断的是他们存储的内存地址是否相同,由上图可见,他们的内存地址是相同的,所以例一输出的是true。

例二原理示意图

例二的两个字符串都是通过new的方式创建对象的,所以在字符串常量池中有两个值为“wo”的对象,如上图所示,此时str2和str3存储的对象地址就不相同,所以例二返回的是false。

3 总结

==使用总结

  • 如果是基本数据类型,==判断的是值
  • 如果是对象类型,==判断的是对象的地址

其它总结

  • 通过直接赋值而不是new的方式给String赋值,如果字符串常量池中有该对象,则不会再创建,此时通过 == 判断,返回的是true。如:String str="wo";String str1="wo";str == str1为true.
  • 在JDK1.6及以前版本,字符串常量池在方法区中;在JDK1.7及以后,字符串常量池在堆中。
  • 对象的引用保存在栈中
上一篇 下一篇

猜你喜欢

热点阅读