JVM运行时,会将内存分为两个部分:堆和栈。堆中存放的是创建的对象,而栈中存放的方法调用过程的局部变量或引用。而设计Java字符串对象内存实现的时候,在堆中又开辟了一块很小的内存,称之为字符串常量池,专门用来存放特定的字符串对象。

创建Java字符串对象有两种常用的方式:

String 引用变量名="字符串内容";

String 引用变量名=new String();

我们先来看看创建字符串对象的第一种方式内存如何分配的,代码如下:

String s1="osEye.net";

String s2="osEye.net";

如上图描述了引用对象的关系,以及内存的分配。Java实现的步骤如下:

查看字符串常量池中是否存在内容与“osEye.net”相同的字符串对象。

若没有,则新创建一个包含该内容的字符串对象,并让引用变量指向该对象。例如,创建字符串s1的时候,字符串常量池中没有,则创建一个新对象,并让引用s1指向该对象。

若已经存在包含该内容的字符串对象,则让字符串引用直接指向该对象。例如,在创建字符串s2的时候,字符串常量池中已经有包含该内容的对象了,所以引用s2直接指向已有的对象。

在来看看第二种创建字符串对象的方式:

String s1="osEye.net";

String s2=new String("osEye.net");

如上图描述了引用对象的关系,以及内存的分配。Java实现的步骤如下:

首先在堆(不是常量池)中创建一个包含指定内容的字符串对象,并将字符串引用指向该对象。例如上述代码中,使用new创建字符串s3,其会直接在堆中创建一个内容为“osEye.net”的字符串对对象,并将引用s3指向该对象。

去字符串常量池中查看,是否有包含该内容的对象。

若有,则将new出来的字符串对象与字符串常量池中内容相同的对象联系起来。例如,本例中s3所指向的对象与s1所指向的联系起来。

若没有,则在字符串常量池再创建一个包含该内容的字符串对象,并将堆中的对象与字符串常量池中新创建出来的对象联系起来。

我们知道,new出来的字符串对象和字符串常量池中的对象是有联系的,可以通过intern方法来查看,方法签名:

public String intern()

此方法将指定的字符串引用在字符串常量池中对应的对象,若其指向的对象本身就在字符串常量池中,则直接将自己指向的对象返回;若该字符串引用指向的对象在堆中,则返回字符串常量池中与其联系的对象。实例如下:

package net.oseye;

public class ExceptionTest {

public static void main(String[] args) {

String s1="osEye.net";

String s2=new String("osEye.net");

if(s1==s2){

System.out.println("字符串引用s1和字符串引用s2所指向的是同一个对象");

}else{

System.out.println("字符串引用s1和字符串引用s2所指向的不是同一个对象");

}

if(s1.intern()==s2.intern()){

System.out.println("字符串引用s1和字符串引用s2在字符串常量池中联系的是同一个对象");

}else{

System.out.println("字符串引用s1和字符串引用s2在字符串常量池中联系的不是同一个对象");

}

}

}

输出结果:

字符串引用s1和字符串引用s2所指向的不是同一个对象

字符串引用s1和字符串引用s2在字符串常量池中联系的是同一个对象

java string 内存写了_Java String的内存机制相关推荐

  1. java字符串常量池长度_Java String类相关知识梳理(含字符串常量池(String Pool)知识)...

    目录 1. String类是什么 1.1 定义 1.2 类结构 1.3 所在的包 2. String类的底层数据结构 3. 关于 intern() 方法(重点) 3.1 作用 3.2 字符串常量池(S ...

  2. java 方法特点是什么_Java String 的特点是什么?它有哪些重要的方法?

    以主流的 JDK 版本 1.8 来说,String 内部实际存储结构为 char 数组,源码如下: public final classStringimplements java.io.Seriali ...

  3. java nio 追加写文件_Java NIO在文件末尾追加数据

    [java]代码库import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; import ja ...

  4. java 内存模型面试_Java面试- JVM 内存模型讲解

    经常有人会有这么一个疑惑,难道 Java 开发就一定要懂得 JVM 的原理吗?我不懂 JVM ,但我照样可以开发.确实,但如果懂得了 JVM ,可以让你在技术的这条路上走的更远一些. JVM 的重要性 ...

  5. java 内存分配实例_java学习(四) —— 内存分配浅析

    前言 java中有很多类型的变量.静态变量.全局变量及对象等,这些变量在java运行的时候到底是如何分配内存的呢?接下来有必要对此进行一些探究. 基本知识概念: (1)寄存器:最快的存储区, 由编译器 ...

  6. java 内存分配管理_JAVA实验操作系统内存管理-最优分配,最先分配,最坏分配算法...

    package Memory; import java.util.ArrayList; import java.util.Iterator; import java.util.Scanner; pub ...

  7. python string转date类型_java string类型怎么转化成date类型

    /** * 根据一段日期时间字符串,转换得到日期时间对象.日期时间字符串可以是以下格式: * 1. yyyy-MM * 2. yyyy-MM-dd * 3. HH:mm * 4. HH:mm:ss * ...

  8. java 堆内存和栈内存的区别_java中栈内存和堆内存有什么区别

    栈内存和堆内存的区别: 1.栈内存用来存放基本类型的变量和引用变量,堆内存用来存储java中的对象,无论是成员变量,局部变量,还是类变量,他们指向的对象都存储在堆内存中. (视频教程推荐:java视频 ...

  9. java 判断数字变化增减_java String 强化操作 判断数字 字符串转阿拉伯数字,相似度等等...

    importjava.io.BufferedReader;importjava.io.StringReader;importjava.util.ArrayList;importjava.util.Li ...

最新文章

  1. zip 文件下载函数封装
  2. python初级数据分析师薪资_学会数据分析,薪资翻倍?!
  3. 键盘敲入 A 字母时,操作系统期间发生了什么...
  4. 使用vivado进行逻辑开发时,进行到Generate Bitstream时报错
  5. motionVFX mRevealer Glitch Mac(fcpx插件:30个故障干扰马赛克毛刺失真特效)
  6. 算法题---最长公共前缀
  7. 基于visual Studio2013解决C语言竞赛题之1033数字交换
  8. CDOJ 1330 柱爷与远古法阵(高斯消元)
  9. 一百个人眼中的一百种爱情
  10. Visio2010正确的安装步骤
  11. EJB开发web service
  12. 安:[摩斯密码表]摩斯密码对照表
  13. django面试题总结
  14. 基片集成波导原理_基片集成波导
  15. OpenCV————鼠标绘制和滑动条
  16. 2020年TI杯大学生电子设计大赛 无线运动传感器节点 备赛、参赛实录(历时一个月)
  17. C++ nth_element 介绍
  18. 2020第二场NOIP|题解
  19. 阿里云中间件2024届校园招聘
  20. 以let开头的祈使句用法归纳

热门文章

  1. Java编程思想—第十二十三章
  2. Netty技术细节源码分析-内存池之PoolChunk设计与实现
  3. 怎么在anaconda上安装python_win10肿么在已安装python2.7的基础上安装anaconda
  4. 【教你如何放大招】程序猿是如何一点点的吃下一个产品的
  5. JVM 内存模型组成+经典总结
  6. 大厂面试算法系列-如何实现链表的逆序(二)-递归法
  7. Go 把类型放在变量名后面,是特立独行还是另有机密?
  8. Go内存管理之代码的逃逸分析
  9. 容器和虚拟机到底有啥区别?
  10. java 属性默认_【急】求教如何设置javabean中某几个属性的默认值