字符串的不可变性(String的不可变性)Integer的常量池

版权声明:Please make the source marked https://blog.csdn.net/qq_31807385/article/details/83030967

JVM的内存分配图:

PC寄存器:会记录各个线程的执行位置

Java方法栈:面向java方法

本地方法栈:面向本地方法(用C++ 写的native方法)

方法区:加载后的Java类会被存放在java方法区,代码实际运行的时候,虚拟机会执行方法区内的代码。

为什么字符串是不可变的?

因为字符串的底层使用的是数组存储,数组的长度是不可变的。且使用final,private修饰,不能直接方法,String也没有提供直接修改的方法。

由此我们知道:String一旦被创建,则不能被修改,所谓的修改也只是创建了新的对象。

字符串常量在内存中的位置:

字符串常量对象存储在常量池中,jdk1.6及之前在方法区中,jdk1.7之后堆中特殊的区域中;jdk1.8,在元空间中(元空间是方法区的一种体现)

String str1 = new String(“hello”);
String str2 = “hello”;
System.out.println(str1 == str2);//false; 

第一句代码创建了几个对象?

字符串常量池中有一个对象,堆中有一个字符串对象;
堆中的字符串对象指向了常量池中常量对象的"hello";str1,str2在栈中;
new String("hello")在堆中;"hello"字符串常量在常量池中

 为什么是false?

str1引用在栈中,指向了堆中的对象,str2引用在栈中指向常量池(方法区),两者的地址是不一样的。 请注意:字符串常量中的字符串也是对象,堆中的字符串对象都是指向了字符串常量池中的对象的。

String str1 = "hellojava";
String str2 = "hello" +"java";
System.out.println(str1 == str2);//true

为什么是true?

hellojava作为一个字符串(常量)对象在字符串常量池中存在,java编译器发现hello和java是两个常量,
是字符串的拼接,拼接之后仍然是字符串常量对象,依然存储在常量池中,发现常量池中有这个常量对象,
直接将栈中的引用str2指向该存在的常量对象。这里的注意:没有涉及到变量的运算,相同的字符串不会产生新的对象
String str1 = "hello";
String str2 = "java";
String str3 = "hellojava";
String str4 = str1 + "java";
String str5 = str1 + str2;

System.out.println(str3 == str4);//false
System.out.println(str3 == str5);//false

为什么是这个结果?

详解:str1指向常量池中的常量对象hello str2指向常量池中的常量对象java,str3指向常量池中的常量对象hellojava。str4 和 str5 都涉及到了String对象,实际会产生新的对象存储在堆中,而str3 指向的是常量池(方法区中)
总结:变量参与运算(拼接),一定会产生新的对象。对象在堆中

关于String对象的图解

(1)

(2)

任何的类型都有常量池的概念,比如说

比如下面的代码:

package hello_java;

public class Test {
    public static void main(String[] args) {
        Integer i1 = 127;
        Integer i2 = 127;

        Integer i3 = 128;
        Integer i4 = 128;
        System.out.println(i1 == i2);
        System.out.println(i3 == i4);
    }
}

true
false

 为甚呢?看下面的源码,重新创建一个Integer的对象的时候,首先看值的范围,如果在该方位内的话,就使用常量池中的值。

    public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

猜你喜欢

转载自blog.csdn.net/qq_31807385/article/details/83030967