在Java的内存分配中,总共3种常量池: Java 常量池详解(二)class文件常量池 和 Java 常量池详解(三)class运行时常量池 1.字符串常量池(String Constant Pool...) 在JDK1.7之前运行时常量池逻辑包含字符串常量池存放在方法区, 此时hotspot虚拟机对方法区的实现为永久代 在JDK1.7 字符串常量池被从方法区拿到了堆中, 这里没有提到运行时常量池,也就是说字符串常量池被单独拿到堆..., 只不过方法区的实现从永久代变成了元空间(Metaspace) 1.1:字符串常量池在Java内存区域的哪个位置?...(堆内是可以进行回收的,然后方法区也是能回收的,但是本身区域内存比较少,如果用的字符串常量太多了,也会抛java.lang.OutOfMemoryError:PermGenspace 异常) 1.2:字符串常量池是什么...如果常量池中没有此字符串, 会将此字符串放入常量池中后, 再返回 native实现代码: \openjdk7\jdk\src\share\native\java\lang\String.c Java_java_lang_String_intern
形式上: 字符常量是单引号引起的一个字符; 字符串常量是双引号引起的若干个字符 含义上: 字符常量相当于一个整型值( ASCII 值),可以参加表达式运算; 字符串常量代表一个地址(该字符串在内存中存放位置...) 占内存大小 字符常量只占2个字节; 字符串常量占若干个字节(至少一个字符结束标志) (注意: char在Java中占两个字节) java编程思想第四版:2.2.2节 ?
大家好,又见面了,我是你们的朋友全栈君。 字符串 字符串字面量:就是指这个字符串本身,比如”Java”,”Hello”。...这两项就是java和abcd这两个字符串的字面量。 而符号引用也是一些常量,比如全限定类名,字段的名称和描述符,方法的名称和描述符。 这是类名。 这是变量名。...c=”java”; String d=”abcd”; String e=”java”; String f=new String(“java”); } } 运行时常量池 && 字符串常量池 class常量池被加载到内存后...运行时常量池相对于class常量池的一个特点是具有动态性,Java不要求所有常量在编译器产生,可以在运行时产生常量加入常量池,例如String类的intern()。...意思是当一个字符串对象调用intern方法,如果池中已经存在值相等(通过String的equal函数比较)的字符串常量,就返回常量池中的常量,也就是堆中对应实例的引用。否则将这个字符串加入常量池。
JVM通过字符串常量池查找不到内容为droid的字符串对象存在,那么会创建这个字符串对象,然后将刚创建的对象的引用放入到字符串常量池中,并且将引用返回给变量str1。...字符串常量池实现的前提条件就是Java中String对象是不可变的,这样可以安全保证多个变量共享同一个对象。...如果Java中的String对象可变的话,一个引用操作改变了对象的值,那么其他的变量也会受到影响,显然这样是不合理的。 引用 or 对象 字符串常量池中存放的时引用还是对象,这个问题是最常见的。...字符串常量池存放的是对象引用,不是对象。在Java中,对象都创建在堆内存中。 更新验证,收到的很多评论也在讨论这个问题,我简单的进行了验证。...我们通过设置永久代一个很小的值来进行验证。如果字符串对象存在字符串常量池中,那么必然抛出java.lang.OutOfMemoryError permgen space错误。
在解析阶段,会把符号引用替换为直接引用,解析的过程会去查询字符串常量池,也就是StringTable,以保证运行时常量池所引用的字符串与字符串常量池中是一致的。...字符串常量池 字符串常量池在Java内存区域的哪个位置? 在JDK6.0及之前的版本,字符串常量池是放在Perm Gen区(也就是方法区)中; 在JDK7.0版本,字符串常量被移到了堆中。...在之前版本中,里放的都是字符串常量 在中,由于发生了改变,因此中也可以存放放置在堆内的字符串对象的引用。...⚠️字符串常量池中的字符串只存在一份,且被所有线程共享 ⚠️全局字符串池里的内容是在类加载完成,经过验证、准备阶段之后在堆中生成字符串对象实例,然后将该字符串对象实例的引用值存到中;中存的是引用值而不是具体的实例对象...在JDK1.7字符串常量池和静态变量被从方法区拿到了堆中,运行时常量池剩下的还在方法区,也就是HotSpot的永久代中。
参考链接: Java字符串之-intern() // ==与equals的区别: // ==: // 1、比较的是操作符两端的操作数是否是同一个对象 // 2、两边的操作数必须是同一类型的(可以是父子类之间... * * 它是java中唯一不需要new 就可以产生对象的途径. * * 以 String s=”abce”;形式赋值在java中叫直接量,它是在常量池中而不是象new 一样放在压缩堆中.... * 这种形式的字符串,在JVM内部发生字符串拘留,即当声明这样的一个字符串后,JVM会在常量池中先查找有有没有一个值为”abcd”的对象,如果有,就会把它赋给当前引用.即原来那个引用和现在这个引用指点向了同一对象...产生差异的原因是:在JDK1.6中,intern()方法会把首次遇到的字符串实例复制到永久代(常量池)中,返回的也是永久代中这个字符串实例的引用,而由StringBuilder创建的字符串实例在Java...对str2比较返回false是因为”java”这个字符串在执行StringBuilder.toString()之前已经出现过,字符串常量池中已经有它的引用,不符合“首次出现”的原则,而“计算机软件”这个字符串则是首次出现的
简介: 这几天在看Java虚拟机方面的知识时,看到了有几种不同常量池的说法,然后我就去CSDN、博客园等上找资料,里面说的内容真是百花齐放,各自争艳,因此,我好好整理了一下,将我自认为对的理解写下来与大家共同探讨...: 在Java的内存分配中,总共3种常量池: 1.字符串常量池(String Constant Pool): 1.1:字符串常量池在Java内存区域的哪个位置?...关于String在内存中的存储和String#intern()方法的说明,可以参考我的另外一篇博客: 需要说明的是:字符串常量池中的字符串只存在一份!...(这里具体的字符串如何分配就不细说了,可以看我的另一篇博客) 2.class常量池(Class Constant Pool): 2.1:class常量池简介: 我们写的每一个Java类被编译后,就会形成一份...在解析阶段,会把符号引用替换为直接引用,解析的过程会去查询字符串常量池,也就是我们上面所说的StringTable,以保证运行时常量池所引用的字符串与字符串常量池中是一致的。
由于String字符串的不可变性我们可以十分肯定常量池中一定不存在两个相同的字符串(这点对理解上面至关重要)。 Java中的常量池,实际上分为两种形态:静态常量池和运行时常量池。...所以上面应该产生了两个对象:保存在栈中的c和保存堆中chenssy。但是在Java中根本就不存在两个完全一模一样的字符串对象。故堆中的chenssy应该是引用字符串常量池中chenssy。...而字符串引用的”+”运算是在Java运行期间执行的,即str + str2 + str3在程序执行期间才会进行计算,它会在堆内存中重新创建一个拼接后的字符串对象。...对于直接相加字符串,效率很高,因为在编译器便确定了它的值,也就是说形如”I”+”love”+”java”; 的字符串相加,在编译期间便被优化成了”Ilovejava”。...String的intern()方法就是扩充常量池的一个方法;当一个String实例str调用intern()方法时,java查找常量池中是否有相同unicode的字符串常量,如果有,则返回其引用,如果没有
大家好,又见面了,我是你们的朋友全栈君 JVM——字符串常量池详解 引言 在Java开发中不管是前后端交互的JSON串,还是数据库中的数据存储,我们常常需要使用到String类型的字符串。...字符串常量池由来 在日常开发过程中,字符串的创建是比较频繁的,而字符串的分配和其他对象的分配是类似的,需要耗费大量的时间和空间,从而影响程序的运行性能,所以作为最基础最常用的引用数据类型,Java设计者在...实现原理 为了提高性能并减少内存的开销,JVM在实例化字符串常量时进行了一系列的优化操作: 在JVM层面为字符串提供字符串常量池,可以理解为是一个缓存区; 创建字符串常量时,JVM会检查字符串常量池中是否存在这个字符串...方法区和Java堆一样(但是方法区是非堆),是各个线程共享的内存区域,是用于存储已经被JVM加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。 ...当然,对于JDK1.8时,HostSpot VM对JVM模型进行了改造,将元数据放到本地内存,将常量池和静态变量放到了Java堆里。
形式上: 字符常量是单引号引起的一个字符;字符串常量是双引号引起的 0 个或若干个字符。 2....含义上: 字符常量相当于一个整型值( ASCII 值),可以参加表达式运算;字符串常量代表一个地址值(该字符串在内存中存放位置)。...因为Java在内存中总是使用Unicode表示字符,所以,一个英文字符和一个中文字符都用一个char类型表示,它们都占用两个字节。...占内存大小:字符常量只占 2 个字节;字符串常量占若干个字节 (注意:char 在 Java 中占两个字节)。 4....Java语言要确定每种基本类型所占的存储空间大小。基本类型的大小不会随硬件架构的变化而变化。这种存储空间大小的不变性是Java语言具有可移植性的主要原因之一。 ?
大家好,又见面了,我是你们的朋友全栈君。 JAVA变量与常量 常量 常量值 常量 常量的声明定义 常量 常量在c语言编程网中的定义是指在程序的整个运行过程中值保持不变的量。...在这里要注意常量和常量值是不同的概念,常量值是常量的具体和直观的表现形式,常量是形式化的表现。...这里体现出常量值这一定义,我认为的常量值就是值,具体的某一数值 百度出来的常量是定义为两种意思:一是不可变的变量,也是最最最开始接触java知道的,二如上。...这是测试\\r与\\n的区别 测试如下:测试数据\r\n一大堆字符串事实测试\r大堆字符串事实测试\n\r一大堆字符串事实测试\r大堆字符串事实测试\n一大堆字符串事实测试"); } //结果如下...这是测试\r与\n的区别 测试如下:测试数据 一大堆字符串事实测试 大堆字符串事实测试 一大堆字符串事实测试 大堆字符串事实测试 一大堆字符串事实测试 //如上所示是我在eclipse中运行的,
字符串在Java生产开发中的使用频率是非常高的,可见,字符串对于我们而言非常关键。...Java中是如何实现字符串的 那其实在Java中,关于字符串的实现,其实用的也是char数组,这可以从源码中得到体现。...而Java虚拟机如果发现常量池中已经存在需要创建的字符串中,它就不会重复创建,而是指向那个字符串即可。 ?...字符串驻留 当相同的字符串常量被多次创建时,注意是使用双引号(" ")显式声明时,字符串常量对象会被保存在常量池中,且只会创建一个对象,这就是字符串驻留,这个名词的产生就是为了提升性能。...该方法会去常量池中寻找当前调用该方法的字符串常量,若找到,则直接返回该字符串对象,若没有,则将当前字符串放入常量池并返回,总之该方法一定会返回字符串。
常量字符串与存放在栈中的字符串是C语言面试中经常出现的问题,这可以考察面试者对于C语言数据存储的理解。 我们通过几个例题来看看常量字符串与存放在栈中的字符串 下面的程序有错误吗?为什么? ...,是一个常量字符串,存放于只读的段中,是不可被修改的!向只读数据段写入数据会产生段错误,那么,我们怎么让这个程序合法呢?...; str[0] = 'H'; printf(str) ; } 这样,程序会为str分配地址,str指向的是栈中合法的地址,字符串存放于栈中,是可以被更改的
★ 有的时候博客内容会有变动,首发博客是最新的,其他博客地址可能会未同步,认准https://blog.zysicyj.top ” Java 中的字符型常量和字符串常量是两种不同的数据类型。...字符串常量:字符串常量是由多个字符组成的,用双引号括起来。例如:"Hello", "World"等。在内存中,字符串常量以字符数组的形式存在,并且每个字符都有一个对应的 Unicode 编码值。...长度不同:字符型常量只能包含一个字符,而字符串常量可以包含任意数量的字符。 内存表示不同:字符型常量在内存中占用 2 个字节,字符串常量在内存中以字符数组的形式存在。...操作方法不同:字符型常量可以进行一些基本的字符操作,如比较、转换大小写等;字符串常量则可以进行更复杂的字符串操作,如连接、截取、替换等。...(result); // 输出:Hello World 总结: 字符型常量和字符串常量在 Java 中是两种不同的数据类型,分别用于表示单个字符和多个字符组成的字符串。
字符串常量到底是怎么回事?本来这个问题快要清楚了,一出现字符串常量,一下子又复杂了。...h2实际上呢是一个字符串常量,它和h3是同一个对象好像也是对的。...这是因为字符串常量,在class文件的常量池中,当执行到ldc指令去访问这个常量的时候,如果该常量是一个字符串类型,hotspot就会在后面默默地创建一个字符串,并且,调用intern方法!...Java在加载字符串常量的时候会调用一遍intern,那么StringTable里就会留下这个hotspot默认创建的字符串。 好了。回到原问题。...所以h2和h1会是相等的,都是StringTable里的这个默认字符串。 而s3因为是计算得来的,不是字符串常量,所以手动调用s3.intern()时,StringTable里留下的就是s3。
大家好,又见面了,我是你们的朋友全栈君。 JAVA常量就是在程序中固定不变的值,是不能改变的数据。例如数字1、字符“a”、浮点数3.2等。那么java的常量有哪些呢?...在Java中,常量包括整型常量、浮点数常量、布尔常量、字符常量等。 下面我们就一起来看看java中的这些常量。...4.字符串常量 字符串常量用于表示一串连续的字符,一个字符串常量要用一对英文半角格式的双引号””引起来,具体示例如下: “HelloWorld”“123″”Wecome XXX””” 一个字符串可以包含一个字符或者多个字符...以上就是动力节点java学院小编针对“Java中的常量有哪些?”...的内容进行的回答,希望对大家有所帮助,如果对于学习Java的学习计划,怎么学才有效率,或者学完如果找工作的问题,请在线咨询,有专业老师随时为你服务。
大家好,又见面了,我是你们的朋友全栈君。 字符串常量池 StringTable 概述 常量池在java用于保存在编译期已确定的,已编译的class文件中的一份数据。...它包括了关于类,方法,接口等中的常量,也包括字符串常量,如String s = “java”这种申明方式;当然也可扩充,执行器执行器产生的常量也会放入常量池,故认为常量池是JVM的一块特殊的内存空间。...被final修饰,无法被继承 String与字符串常量池 在Java语言中有8种基本数据类型和一种比较特殊的类型String。...这个后面重点谈 Java 6及以前,字符串常量池存放在永久代 Java 7中 Oracle的工程师对字符串池的逻辑做了很大的改变,即将字符串常量池的位置调整到Java堆内 所有的字符串都保存在堆...字符串常量池概念原本使用得比较多,但是这个改动使得我们有足够的理由让我们重新考虑在Java 7中使用String.intern()。 Java8元空间,字符串常量在堆中。
我直接否定了三妹的答案,“使用 new 关键字创建一个字符串对象时,Java 虚拟机会先在字符串常量池中查找有没有‘二哥’这个字符串对象,如果有,就不会在字符串常量池中创建‘二哥’这个对象了,直接在堆中创建一个...我回答,“由于字符串的使用频率实在是太高了,所以 Java 虚拟机为了提高性能和减少内存开销,在创建字符串对象的时候进行了一些优化,特意为字符串开辟了一个字符串常量池。”...通常情况下,我们会采用双引号的方式来创建字符串对象,而不是通过 new 关键字的方式: String s = "三妹"; 当执行 String s = "三妹" 时,Java 虚拟机会先在字符串常量池中查找有没有...“那哥,字符串常量池在内存中的什么位置呢?”三妹问。 我说,“三妹,你这个问题问得好呀!” 在 Java 8 之前,字符串常量池在永久代中。 ?...Java 8 之后,移除了永久代,字符串常量池就移到了堆中。 ? “哥,能再简单给我解释一下方法区,永久代和元空间的概念吗?有点模糊。”三妹说。 我说,“可以呀。”
Java文件被编译成 Class文件,Class文件中除了包含类的版本、字段、方法、接口等描述信息外,还有一项就是常量池,常量池是当Class文件被Java虚拟机加载进来后存放在方法区 各种字面量 (Literal...运行时常量池是当Class文件被加载到内存后,Java虚拟机会 将Class文件常量池里的内容转移到运行时常量池里(运行时常量池也是每个类都有一个)。...运行时常量池相对于Class文件常量池的另外一个重要特征是具备动态性,Java语言并不要求常量一定只有编译期才能产生,也就是并非预置入Class文件中常量池的内容才能进入方法区运行时常量池,运行期间也可能将新的常量放入池中...堆里边的字符串常量池存放的是字符串的引用或者字符串(两者都有) 比如new String(“test”)就会先在常量池中检查是否存在,不存在则在常量池中创建,然后堆中创建其引用。...② jdk 1.7及以后:直接将堆中(不是字符串常量池中)该字符串的地址复制到字符串常量池中,这样字符串常量池就有了该字符串的地址引用,也可以说此时字符串常量池中的字符串只是一个对 堆中字符串对象的引用
大家好,又见面了,我是你们的朋友全栈君。 在Java语言中,主要是利用final关键字来定义常量。当常量被设定后,一般情况下就不允许再进行更改。...为此可以使用final关键字来定义一个常量的数组。这就是Java语言中一个很大的特色。...不同的语言,在定义变量或者常量的时候,都有自己一套编码规则。这主要是为了提高代码的共享程度与提高代码的易读性。在Java语言中,定义常量的时候,也有自己的一套规则。...如在给常量取名的时候,一般都用大写字符。在Java语言中,大小写字符是敏感的。之所以采用大写字符,主要是跟变量进行区分。虽然说给常量取名时采用小写字符,也不会有语法上的错误。...总之,Java开发人员需要注意,被定义为final的常量需要采用大写字母命名,并且中间最好使用下划线作为分隔符来进行连接多个单词。
领取专属 10元无门槛券
手把手带您无忧上云