`
Heis
  • 浏览: 114789 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

三分钟理解Java中字符串(String)的存储和赋值原理

阅读更多

可能很多java的初学者对String的存储和赋值有迷惑,以下是一个很简单的测试用例,你只需要花几分钟时间便可理解。

1.在看例子之前,确保你理解以下几个术语:

 

:由JVM分配区域,用于保存线程执行的动作和数据引用。栈是一个运行的单位,Java中一个线程就会相应有一个线程栈与之对应。

 

:由JVM分配的,用于存储对象等数据的区域。

 

常量池 :在堆中分配出来的一块存储区域,用于存储显式 的String,float或者integer.例如String str="abc"; abc这个字符串是显式声明,所以存储在常量池。

 

2.看这个例子,用JDK5+junit4.5写的例子,完全通过测试

import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertSame;

import org.junit.Test;

/**
 * @author Heis
 *
 */
public class StringTest{

	@Test
	public void testTheSameReference1(){
		String str1="abc";
		String str2="abc";
		String str3="ab"+"c";
		String str4=new String(str2);
		
		//str1和str2引用自常量池里的同一个string对象
		assertSame(str1,str2);
		//str3通过编译优化,与str1引用自同一个对象
		assertSame(str1,str3);
		//str4因为是在堆中重新分配的另一个对象,所以它的引用与str1不同
		assertNotSame(str1,str4);
	}
	
}

 

  • 第一个断言很好理解,因为在解析的时候,"abc"被存储在常量池中,str1和str2的引用都是指向常量池中的"abc"。所以str1和str2引用是相同的。
  • 第二个断言是由于编译器做了优化,编译器会先把字符串拼接,再在常量池中查找这个字符串是否存在,如果存在,则让变量直接引用该字符串。所以str1和str3引用也是相同的。
  • str4的对象不是显式赋值的,编译器会在堆中重新分配一个区域来存储它的对象数据。所以str1和str4的引用是不一样的。


  • 大小: 62.7 KB
17
4
分享到:
评论
12 楼 asialee 2010-01-09  
这个编译优化我还真不知道,谢谢lz了。
11 楼 grunt1223 2010-01-06  
sgelove 写道
package test;

public class Test {
	public static void main(String[] args) {
		String a = "abc";
		String b = "abc";
		String c = "ab" + "c";
		String d = new String(b);
		System.out.println(a.hashCode());
		System.out.println(b.hashCode());
		System.out.println(c.hashCode());
		System.out.println(d.hashCode());
	}
}

为什么我打印出来的d和a,b,c的是一样呢?


HashCode本身就是根据字符内容计算而得的,当然一样了
比较的是引用啊~~~
10 楼 Heis 2010-01-06  
sgelove 写道
package test;

public class Test {
	public static void main(String[] args) {
		String a = "abc";
		String b = "abc";
		String c = "ab" + "c";
		String d = new String(b);
		System.out.println(a.hashCode());
		System.out.println(b.hashCode());
		System.out.println(c.hashCode());
		System.out.println(d.hashCode());
	}
}

为什么我打印出来的d和a,b,c的是一样呢?

因为你的变量a,b,c,d的值都是"abc",哈希值是由string的值计算出来的,当然相同。
9 楼 sgelove 2010-01-06  
package test;

public class Test {
	public static void main(String[] args) {
		String a = "abc";
		String b = "abc";
		String c = "ab" + "c";
		String d = new String(b);
		System.out.println(a.hashCode());
		System.out.println(b.hashCode());
		System.out.println(c.hashCode());
		System.out.println(d.hashCode());
	}
}

为什么我打印出来的d和a,b,c的是一样呢?
8 楼 Heis 2010-01-05  
melin 写道
常量池是存放在方法区中,你那个图画的有点问题。

方法区也是在堆中的,图到底有什么问题呢?
7 楼 melin 2010-01-05  
常量池是存放在方法区中,你那个图画的有点问题。
6 楼 hanjiangit 2010-01-04  
还深入点就好了
5 楼 dragonisflying 2010-01-04  
不错,确实可以帮助理解java里的string处理机制
4 楼 wangxiaoxu 2010-01-04  
文章写的不错
3 楼 ZangXT 2010-01-04  
intih 写道
引用
常量池 :在编译的阶段,在堆中分配出来的一块存储区域,用于存储显式 的String

为什么会是在编译阶段呢,内存分配活动应该都是在Runtime

你说的对
其实编译器做的是常量池表,写在class文件中,jvm加载class的时候会根据这个表的信息处理常量池。不过一般都喜欢混着说
2 楼 Heis 2010-01-03  
intih 写道
引用
常量池 :在编译的阶段,在堆中分配出来的一块存储区域,用于存储显式 的String

为什么会是在编译阶段呢,内存分配活动应该都是在Runtime

你说的对,已经做了修改了。查了一下资料,在编译期,class文件里会保存一个本地变量表(local variable table),在解析期JVM才会把这些变量表加载到常量池中。
1 楼 intih 2010-01-03  
引用
常量池 :在编译的阶段,在堆中分配出来的一块存储区域,用于存储显式 的String

为什么会是在编译阶段呢,内存分配活动应该都是在Runtime

相关推荐

    三分钟使用java快速搭建教程步骤

    Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念。三分钟使用java快速搭建运行环境的步骤

    【经验分享】教你三分钟搭建JAVA运行环境

    针对JAVA初学者专门录制了一个3分钟的教学视频,快速搭建java运行环境,让初学者快速实现效果。欢迎收藏下载~

    Java基本语法练习

    数组是存储多个相同类型数据的集合,Java支持一维、二维甚至多维数组。在第三个部分,创建了不同维度的数组并展示了如何初始化和操作数组元素。 选择结构,如if...else和switch语句,是控制程序流程的关键。在实验...

    三分钟学前端JS篇.pdf

    《三分钟学前端JS篇》是一份前端学习资料,旨在帮助读者通过每日三分钟的学习,逐步掌握前端开发中的JavaScript(JS)知识,从基础到进阶再到资深水平。文档中包含了丰富的前端知识点,涵盖了JS基础概念、函数、闭包...

    浅谈三分钟学习Java泛型中T、E、K、V、?的含义

    Java 泛型详解 Java 泛型是 Java SE 1.5 中引入的一项新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。...理解泛型的使用和原理,可以帮助开发者编写更加安全、可重用的代码。

    通达信指标公式源码 拆分三分钟量的主 副图 源码.doc

    7. 绘制红绿三角副图:使用HHVALL和LLVALL函数获取当前股票的最高和最低价,并将其存储在H1和L1变量中。然后,使用CROSSDOT函数绘制红绿三角副图。 8. 绘制高点和低点:使用FILTER函数获取当前股票的高点和低点,并...

    小学二年级数学课前三分钟展示PPT教案.pptx

    在小学二年级的数学教学中,课前三分钟的展示环节是激发学生兴趣、巩固基础知识和提升学习能力的重要组成部分。这个阶段的学生正处在数学概念启蒙的关键时期,因此,设计有效的课前展示活动至关重要。下面,我们将...

    基于Java和C/C的HYLI_SMART_STEP_COUNTER智能手环嵌入式代码与手机客户端开发源码

    本项目为HYLI_SMART_STEP_COUNTER智能手环的嵌入式代码与手机客户端开发源码,采用Java、C和C语言编写,总计114个...该教程包含智能手环的原理图和安卓手机客户端开发,旨在三分钟内帮助读者理解智能硬件的基本原理。

    数学课前三分钟PPT课件.pptx

    通过精心设计的数学课件,如“数学课前三分钟PPT课件.pptx”,教师可以在课堂的前几分钟,利用学生的新鲜感和好奇心,快速地吸引他们的注意力,并将他们带入到一个充满挑战与趣味的学习环境中。以火柴棒游戏为主题的...

    二年级数学三分钟PPT课件.pptx

    这样的教学方法,将抽象的数学原理与孩子们熟悉的问题相结合,让学生在轻松愉快的氛围中学习和成长。 通过这样的课件,我们可以看到,数学教育不仅仅是知识的传递,更是一种思维方式和解决问题能力的培养。它告诉...

    三分钟搞定base64

    ### 三分钟搞定Base64:全面解析与实践 #### 一、Base64简介 ...掌握Base64不仅可以帮助您更好地理解网络安全和数据传输的基本原理,还能让您在实际工作中更加得心应手。希望本文能够为您带来启发和帮助。

    五年级数学课前三分钟PPT课件.pptx

    "五年级数学课前三分钟PPT课件.pptx" 从这个PPT课件中,我们可以提取出以下几个重要的知识点: 1. 掌握数学技巧的重要性:掌握数学技巧是同学们学好数学、培养数学兴趣、提高数学成绩的有效途径。通过掌握数学技巧...

    三分钟快速掌握Java中枚举(enum)

    Java中的枚举(enum)是JDK 1.5引入的一种强大的类型,它允许开发者定义一组固定的、预定义的值,这些值可以被用作类的成员或者在代码中直接使用。枚举类型提升了代码的可读性,同时也提高了安全性,因为枚举值只能...

    Kotlin 编程三分钟入门

    【Kotlin编程三分钟入门】 Kotlin是一种现代的、面向对象的编程语言,设计时考虑了开发者体验,尤其强调简洁性和可读性。它由JetBrains公司开发,初衷是为了提高开发效率,尤其针对Android开发。Kotlin在Java虚拟机...

    课前三分钟演讲稿_课前三分钟演讲稿课前三分钟演讲素材.doc

    在当今快节奏的教育环境中,课前三分钟演讲已经成为学生们锻炼自我的一个重要环节。通过简短而充满力量的演讲,学生们不仅能够提高自己的语言表达能力和思维敏捷性,还能够在公众面前更好地展示自己,锻炼公众演讲...

    小学英语三分钟演讲PPT教案.pptx

    * 介绍了英语阅读的重要性,例如:提高英语阅读速度和理解能力 该资源旨在帮助学生提高英语口语能力、演讲能力和阅读能力,通过一个有趣的英语故事-"老板最大",讲解了英语单词、句子结构和英语演讲技巧。

    14复试心得1

    * Java:机试的题目是课程表管理系统,考察的是 Java 基础,包括字符串操作和 IO 操作。 * 游戏编程:作者提到,游戏编程是很重要的,包括三子棋、黑白子和 dots and boxes 等游戏。 * 数据结构:机试的题目包括纯...

    三分钟看懂ChatGPT

    1. 个人学习:了解ChatGPT的基本原理和功能,探索其在自然语言处理和智能对话方面的应用。 2. 研究和开发:利用ChatGPT进行自然语言处理研究、构建对话系统、开发智能助手等项目。 3. 教学和培训:用于教育领域的...

    智能硬件 2三分钟看懂智能硬件原理.pdf

    通过以上步骤,我们可以理解智能硬件的基本原理,包括硬件组件的选择、连接和控制,以及软件层面的蓝牙通信和数码管显示。这样的实践项目有助于加深对软硬件结合的理解,为未来更多复杂的智能硬件设计打下基础。

    thymeleaf-study.rar

    在Java中,我们可以使用`java.util.Random`类生成随机数,再结合字符集构建验证码字符串。为了提高安全性,验证码长度通常设置为4-6位。 3. **验证码存储与匹配**:验证码需要存储在服务器端,以便用户提交时进行...

Global site tag (gtag.js) - Google Analytics