字符串常量池在堆中还是方法区,运行时常量池存放什么
- 开发语言
- 2023-08-13
- 93
大家好,如果您还对字符串常量池在堆中还是方法区不太了解,没有关系,今天就由本站为大家分享字符串常量池在堆中还是方法区的知识,包括运行时常量池存放什么的问题都会给大家分析...
大家好,如果您还对字符串常量池在堆中还是方法区不太了解,没有关系,今天就由本站为大家分享字符串常量池在堆中还是方法区的知识,包括运行时常量池存放什么的问题都会给大家分析到,还望可以解决大家的问题,下面我们就开始吧!
jvm方法区中存放的是什么东jvm方法区
方法区1.放了些什么每个类的结构信息,运行时常量池、字段、方法数据、普通方法、构造方法的字节码内容。(这是规范,不同虚拟机的实现是不同的最典型的就是永久代PermGenspace和元空间Metaspace)实例变量在堆内存中,和方法区无关。2.绝对不是用来放方法的3.这块区域所有线程共享,存在垃圾回收。
在java中为什么String字符串可以作为对象来管理
我们知道,在Java中创建字符串(对象)常见有多种方式:
1、Java字面量
"Java字符串"2、直接定义字符串常量
Stringstr="Java字符串";3、通过实例化String类来创建字符串对象
Stringstr=newString("Java字符串");而Java中的String字符串是可以直接当成对象来操作的,这是什么原理呢?
Java中的字符串本质上都是字符串对象像以上定义“字符串”的方式其实在Java虚拟机中都是生成了字符串对象,只不过这些字符串对象在内存中的存取机制不同的。比如说:
1、字符串字面量、字符串常量池
Java中的字符串字面量就是一对用双引号括起来的字符串,比如:“中国人”。
字符串常量是永生代,通俗的说就是常量池,当遇到Stringstr="字符串"时,编译器会在永生代中检查是否存在这个常量的引用,若存在则直接把地址赋给栈;若不存在则先在永生代中开辟内存空间,然后把地址赋给栈指针。
也就是说,字符串常量池中存放的依旧是字符串对象的引用。
2、实例化字符串对象
这种方式会根据String对象再次创建一个String对象,从堆内存中new一块新内存后将指针赋给栈指针。
综上,无论是哪种方式创建的字符串,其本质依旧是字符串对象,所以在Java中字符串可以当成对象来管理。
以上就是我的观点,对于这个问题大家是怎么看待的呢?欢迎在下方评论区交流~我是科技领域创作者,十年互联网从业经验,欢迎关注我了解更多科技知识!字符串常量池是在方法区中还是在独立的区域中
Stringstr="nihao";程序开始执行这句代码,肯定是要创建一个对象的,只是这个对象创建后就是一个常量,不可以更改,并且这个对象是放在串池里面的,也就是你说的那个常量池
如果我后面在写一句代码:Stringother="nihao";
str和other这2个引用的地址就是一样的,因为str和other的声明方式是一样的,都是在串池,str的对象创建时,串池中没有"nihao"这个常量,就创建一个.other对象创建时,发现串池中已经有了"nihao"这个常量,就直接拿过来用就是了
Stringa1=newString("nihao");
Stringb1=newString("nihao");
但是如果我们通过上面的方式直接newString()那个a1和b1这2个引用的对象就不是在串池中了,而是在堆中,但是newString()的参数"nihao"也是一个字符串啊,这个字符串从哪里来呢?如果我们吧代码拆分一下就明白了:
Stringpara="nihao";
Stringa1=newString(para);
就会发现Stringa1=newString("nihao");这一句代码实际上创建了2个对象,一个是String对象,存放在堆中,一个是字符串常量对象,存放在串池中
Java中的字符串常量池与Java中的堆和栈的区别
java常量池不在堆中也不在栈中,是独立的内存空间管理。
1.栈:存放基本类型的变量数据和对象的引用,但对象本身不存放在栈中,而是存放在堆(new出来的对象)或者常量池中(字符串常量对象存放在常量池中。)
2.堆:存放所有new出来的对象。
3.常量池:存放字符串常量和基本类型常量(publicstaticfinal)。
对于字符串:其对象的引用都是存储在栈中的,如果是编译期已经创建好(直接用双引号定义的)的就存储在常量池中,如果是运行期(new出来的)才能确定的就存储在堆中。对于equals相等的字符串,在常量池中永远只有一份,在堆中有多份。
为什么String在java中是不可变的
String类在Java中被设计成不可变的,这是Java开发人员大家都知道的事情。但是要让大家真的说出来为什么String在Java中是不可变的,有时候真的能让人一时语塞,或者说的不够全面。这个问题有各种提问的方式,例如:“为什么Java中要把String类设计成不可变的?”,“String类被设计成不可变类有什么好处?”基本上都是一个思路。
接下来个人从以下几个方面来谈谈自己对这个问题的看法:
什么是不可变?《EffectiveJava》中对于不可变类的解释如下:
不可变类只是其实例不能被修改的类。每个实例中包含的所有信息都必须在创建该实例的时候就提供,并且在对象的整个生命周期内固定不变。为了使类不可变,要遵循下面五条规则:
1.不要提供任何会修改对象状态的方法。
2.保证类不会被扩展。一般的做法是让这个类称为的,防止子类化,破坏该类的不可变行为。
3.使所有的域都是final的。
4.使所有的域都成为私有的。防止客户端获得访问被域引用的可变对象的权限,并防止客户端直接修改这些对象。
5.确保对于任何可变性组件的互斥访问。如果类具有指向可变对象的域,则必须确保该类的客户端无法获得指向这些对象的引用。
不可变带来的好处多线程安全:不可变对象天生多线程安全。因为不可变对象不会被改变,所以它们可以被多线程共享,不需要增加额外的同步操作。字符串池:上面的代码只会创建一个对象实例到JavaHeap中,当创建str1时候,会去字符串池中查看是否已经有了这个字符串,如果有,那么把str1的引用直接指向这个字符串实例上去,这样便极大的节省了内存空间的使用。如果字符串可变的话,那么修改了其中一个对象,就会影响另外一个。
缓存HashCode
当我们创建了一个字符串对象时候,便生成了它的HashCode,因为是不可变,所以生成之后便可以缓存起来,这样用于HashMap中的key,便大大提高了查询的速度。还有我们的Set集合,大家都知道Set集合是不可重复的集合,String类的不可变很好的支持了Set集合的设计思想。String类是基石正是因为有了以String类为代表的这些不可变类,才能为其他对象的构建提供了极大的便利,想想我们在编写Java程序的时候,是不是大量的使用了String类。
以上,就是我个人对Java中为什么String类是不可变的几点看法,大家还有什么更好的见解?欢迎讨论交流,批评指正~
方法区与永久区的区别
方法区(MethodArea)是jvm规范里面的运行时数据区的一个组成部分,jvm规范中的运行时数据区还包含了:pc寄存器、虚拟机栈、堆、方法区、运行时常量池、本地方法栈
永久区也就是永久带,又叫Perm区,只存在于hotspotjvm中,并且只存在于jdk7和之前的版本中,jdk8中已经彻底移除了永久带,jdk8中引入了一个新的内存区域叫metaspace
文章到此结束,如果本次分享的字符串常量池在堆中还是方法区和运行时常量池存放什么的问题解决了您的问题,那么我们由衷的感到高兴!
本文链接:http://www.xinin56.com/kaifa/4017.html