• 以java‘==’理解内存分配


    引言

    public static void main(String[] args) {
    	String str1 = new String("hello");
    	String str2 = "hello";
    	String str3 = new String("hello");
    	String str4 = "hello";
    	System.out.println(str1 == str2);
    	System.out.println(str2 == str3);
    	System.out.println(str3 == str4);
    	String str5;// (str5 = str?)可以用==输出true?
    }
    

    先来一段java代码,如果上面变量都是int之类基本类型,也许结果显然全部相等。但是:

    • 如果现在是字符串呢?
    • 再换为随意创建的对象呢?
    • 再把==换为equals()呢?

    分析

    也许上面代码直接copy到Eclipse下瞬间便知答案,但是为什么?

    首先定义了两组变量(str1,str2与str3,str4),方式一模一样,然后用==计算互相之间差异。
    那么我们就要知道==在java中比较的是地址。好吧,貌似知道了也不能直接解题。似乎还必须了解它们存放地址在哪,这样才知道是否地址相等。那便一个一个分析变量存储内存(java内存介绍便不啰嗦了,可以看这儿)。

    String str1 = new String("hello");
    

    这段代码执行时,用了new关键字,于是在堆中创建了String对象,保存的值便是"hello"(任何对象创建都是类似)。然后在堆栈(栈)中保存一个引用类型(str1)[4个字节,保存地址]。而str1存放的是"hello"这个对象在堆中的地址(可以想象C中指针指向一个实际值,但是java中不存在指针这一说法)。于是每new一个对象,必然在堆中新分配了空间。对于String类型这是绝对的,而且只会在堆中保存对象。但是一个类存在的静态变量,会放在静态变量区,方法体等其他仍在堆中。

    String str2 = "hello";
    

    而执行这段代码时,str2仍然是栈中引用类型,但是java会先在常量池中寻找有没有"hello"这个字符串,如果有,那么str2就初始化为找到的"hello"的引用(不会在任何地方创建新对象)。如果没找到,会在常量池中创建,不同于new,堆中不创建对象。至此,在常量池中和堆中各有一个"hello"。继续:

    String str3 = new String("hello");
    String str4 = "hello";
    

    接下来继续创建"hello"。str3时,又是new,想都不用想,前面str1分析中说了每次new都在堆中新创建对象。ok,现在堆中两个对象了,接着str4呢?继续在常量池创建?当然不,直接等号初始化是在常量池创建,但是前提是没有这个,而str2已经存在于常量池中,那么str4也就引用此处"hello"好了。至此所有创建的对象包括引用状态如下图:
    内存状态
    现在回到代码输出,比较地址?显然只有str2和str4引用同一个"hello" 地址,再其他任意两个地址都不相等。好吧,开始程序输出三个false.

    然后根据自己想法创建一个str5,想等于str1?可以这样String str5 = str1,str3同理。如果想等于str2,或者str4呢,也可以这样?当然,而且还可以这样:

    String str5 = "hello";//为什么?
    

    思考

    如果输出用equals()而不用==呢?

    运行程序,或者直接得出:所有的str都相等。那么么么。。。为什么O(∩_∩)O~?

    看来又要去了解equals()的比较方式

    所有文章未特殊说明均属原创,有误之处欢迎提出,转载随意,您喜欢就好,但请注明,谢谢!
  • 相关阅读:
    蓝桥题库基础练习1-10
    HTML5(八)Web Workers
    对自动化测试工具的实战运用
    对自动化测试工具的简要认识
    HTML5(七)Web 存储
    蓝桥杯javaB组入坑
    Google Play内购测试
    【python】python中的json、字典dict
    【python】python之tuple元组
    性能测试基础知识
  • 原文地址:https://www.cnblogs.com/nonefly/p/4603291.html
Copyright © 2020-2023  润新知