java中的字符串你真的了解吗?

本文深入探讨Java中字符串的实现机制,包括字符串的定义、存储位置、equals方法与==的区别,以及字符串常量池的工作原理。文章详细解释了JVM内存区域,特别是堆和方法区在字符串处理中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  说到字符串,只要是学过点编程的人都知道,都了解,都会用,但是你对字符串真的了解吗?我猜想应该是有一部分人不是很了解。

一:初识字符串
字符串是一定长度的字符序列,长度是任意长,但是不能超过java的最大长度。 大家都知道java有8大基本类型,字符串不属于这8大基本类型,它是由指定的String类来管理的。
字符串的定义方式大致分为2类,声明的时候同时赋值,例如string str =“nihao”;或者先声明后赋值,string str;str=“nihao”;

二:深入了解字符串
如果问大家,字符串最常用的方法是啥?大家肯定回答 :测试字符串是否相等的方法,即equals 方法。在聊这个方法之前,先聊一下所有类的父类Object类的equals方法(等价于==),此方法对于任何非空引用值x和y,当且仅当x和y引用同一个对象时,方法才返回true,也就是说其对比的是内存地址。
String 类的equals方法是重写了Object类的equals方法,当且仅当参数不为null,并且是与此对象表示相同字符列的String对象时,才返回true,也就说对比的是字符串的内容。
那什么是比较内容,什么是比较内存地址呢?

 JVM内存区域分为五个部分,分别是堆,方法区,虚拟机栈,本地方法栈,程序计数器。
 堆。 堆是Java对象的存储区域,任何用new字段分配的Java对象实例和数组,都被分配在堆上,Java堆可使用-Xms -Xmx进行内存控制,值得一提的是从JDK1.7版本之后,运行时常量池从方法区移到了堆上。
  方法区。它用于存储已被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据,方法区在JDK1.7版本及以前被称为永久代,从JDK1.8永久代被移除。
  虚拟机栈。虚拟机栈中执行每个方法的时候,都会创建一个栈帧用于存储局部变量表,操作数栈,动态链接,方法出口等信息。
  本地方法栈。与虚拟机栈发挥的作用相似,相比于虚拟机栈为Java方法服务,本地方法栈为虚拟机使用的Native方法服务,执行每个本地方法的时候,都会创建一个栈帧用于存储局部变量表,操作数栈,动态链接,方法出口等信息。
  程序计数器。指示Java虚拟机下一条需要执行的字节码指令。 
  以上五个区域是Java虚拟机内存划分情况,其中方法区和堆被JVM中多个线程共享,比如类的静态常量就被存放在方法区,供类对象之间共享,虚拟机栈,本地方法栈,pc寄存器是每个线程独立拥有的,不会与其他线程共享。 

所以Java在通过new创建一个类对象实例的时候,一方面会在虚拟机栈中创建一个该对象的引用,另一方面会在堆上创建类对象的实例,然后将对象引用指向该对象的实例。对象引用存放在每一个方法对应的栈帧中。
我们今天讲堆和常量存储区,只要记住凡是new出来的对象都存储在堆中,凡是声明为 final static 的都存储在常量存储区,常量不能变得,String类是final类型的,String作为常量不能修改。
例如:String s1=“hello”;String s1=“hello nihao”;要注意的是:String类对象内容不能修改,但并不代表其引用不能改变//dao
系统专门为String 提供了常量池。 例如 String s1=“hello”;String s2=“hello”; 当声明 s1时会在常量池中产生一个内容为“”“hello”的常量,且让S1指向它,当声明第二个内容一样的字符串时,不会再新增一个字符串,此时会直接将s2也指向“hello”这个字符串。所以S1.equals(s2) 为true,s1==s2。
最后,例如 String s3= new String(“hello”?; String s3= new String(“hello”?;在堆中,只要new出来的都是新对象 ,S1.equals(s2) 为true,s1!=s2。
开心-----

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值