首页 > 编程 > Java > 正文

Java学习(七) String类(1)

2019-11-08 18:28:21
字体:
来源:转载
供稿:网友

字符串内存结构图: 这里写图片描述 注意:字符串在底层的存储实际就是使用字符数组进行存储。 这里写图片描述

String str1 = "javaEE";

首先在栈空间声明一个str1变量,然后看字符串常量池是否存在”JavaEE”,如果不存在,则在字符串常量池中新建”JavaEE”(字符数组)。这个值存在一个首地址,将这个首地址赋给str1。

String str2 = "JavaEE";

字符串常量区已经存在”JavaEE“,所以直接将”JavaEE“的首地址赋给str2。

String str3 = new String("JavaEE");

面试题:上述过程中创建了几个对象?答案是两个。 首先既然是new的,那么就要在堆空间开辟一个区域。但是记住字符串的真正内容并没有放在堆空间中,仍然在字符串常量池中。 这里写图片描述 可以从上面的代码看出:将字符串常量区的”JavaEE“的首地址(value–字符数组名)赋给刚才堆空间new出的一个实体中的value属性,然后再将堆空间中的实体的地址赋给str3.

String str5 = "Android";str5 = str5 + "handoop";

首先也是在栈空间声明一个str5变量,然后看字符串常量池是否存在”Android”,如果不存在,则在字符串常量池中新建”Android”(字符数组)。这个值存在一个首地址,将这个首地址赋给str5。 第二步str5 = str5 + “handoop”;。这个要注意,并不是在字符串常量池中的”Android“后面直接加上”handoop“,而是重新在字符串常量池中新建一个”Androidhandoop“。 至于为什么是重新新建了,而不是在后面添加,这个很好理解。在前面已经提到字符串在底层的存储是以字符数组的形式的,数组在创建的时候大小已经确定了,如果直接在后面添加是不一定能放得下的。 简单示例:

import org.junit.Test;public class TestString { @Test public void test(){ String str1 = "JavaEE"; String str2 = "JavaEE"; String str3 = new String("JavaEE"); String str4 = "JavaEE" + "Android"; String str5 = "Android"; String str6 = str1 + str5; str5 = str5 + "handoop"; String str7 = str6.intern(); String str8 = "JavaEEAndroid"; System.out.PRintln(str1 == str2);//true System.out.println(str1 == str3);//false System.out.println(str1.equals(str3));//true System.out.println(str4 == str6);//false System.out.println(str4.equals(str6));//true System.out.println(str7 == str4);//true System.out.println(str4 == str8);//true Person p1 = new Person("AA"); Person p2 = new Person("AA"); System.out.println(p1.name == p2.name);//true }}class Person{ String name; Person(String name){ this.name = name; }}

有几个地方解释一下: (1)

System.out.println(str4 == str6);//false 为什么?

str4是在编译期就确定的值,为”JavaEEAndroid”。 str6涉及到变量的操作,编译期不确定具体值,加号两边在运行时会转换成new StringBuilder(str1).append(str5).toString(),而这个会产生一个新的字符串对象,所以与str4不相等。

(2)

String str4 = "JavaEE" + "Android"; String str1 = "JavaEE";String str5 = "Android";String str6 = str1 + str5; String str7 = str6.intern(); //intern()的作用是什么?System.out.println(str7 == str4);//true

intern()方法设计的初衷,就是重用String对象,以节省内存消耗。

详情见此 Java技术——你真的了解String类的intern()方法吗

Person p1 = new Person("AA"); Person p2 = new Person("AA"); System.out.println(p1.name == p2.name);//true

从下面的内存结构图中可以看出显然是true。 这里写图片描述


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表