当前位置: 首页 > news >正文

String对象的创建和比较

String类的概述

String类:代表字符串。
Java 程序中的所有字符串字面值(如 “abc” )都作 为此类的实例实现。

String是JDK中内置的一个类:java.lang.string 。
String表示字符串类型,属于引用数据类型,不属于基本数据类型 。
String 类, 创建出来的 对象, 也就是 String对象 。
String是一个final类,代表不可变的字符序列
字符串是常量,用双引号引起来表示。它们的值在创建之后不能更改。
String对象的字符内容是存储在一个字符数组value[]中的。

创建String

日常创建String对象,使用的就是 2种方式 :

🧨字面量方式:
什么是字符串字面量?一个字符串字面量就是两个双引号之间的字符序列,形如“张三”、“zs”。

String str1="字面量";

new 的方式:

String str2 = new String("new");

因为String 是引用数据类型 , 所以str1str2 都是 String 引用数据类型的变量 。这两个String类型的变量存在栈里面

栈 (stack)

存储变量str1str2

栈 (stack) :

  1. 是一个先进后出的数据结构,通常用于保存方法(函数)中的参数,局部变量.
  2. 在java中,所有基本类型和引用类型都在栈中存储.
  3. 栈中数据的生存空间一般在当前scopes内(就是由{…}括起来的区域).
  4. 函数中定义的基本类型变量,对象的引用变量都在函数的栈内存中分配。
  5. 栈内存特点,数数据一执行完毕,变量会立即释放,节约内存空间。
  6. 栈内存中的数据,没有默认初始化值,需要手动设置。

然后String 类 创建的对象,也就是 new String(“new”), 也是需要有东西存。这些东西存在堆里面

堆(heap)

堆内存用来存放new创建的对象和数组。
堆内存中所有的实体都有内存地址值。

🎨创建String对象的2种方式存储情况:
new String(“ACV”) 存在里面。
String str1=“JCccc”; 也是在堆里面,但是是在堆里面的字符串常量池里面。

(现在的java版本是 jdk 8,不考虑字符串常量池的一个位置演变过程了,明确知道一点,jdk7之后,字符串常量池在堆里面 )

字符串常量池(jdk7之后)

为什么明明说好了 堆是用来存对象的,为什么又搞个字符串常量池 ? 也是存对象?

是的,JAVA 设计者确实是这样设计的。

🎈为什么有字符串常量池?

因为我们会发现 String这个引用类型,用起来基本跟其他八个基本类型 (byte、char、short、int、long、float、double、boolean)没有什么区别,甚至String还用的更多。
而且String对象,对象的使用,分配要付出时间和空间上的开销。
既然用的这么勤,我们如果搞一个缓存池给这个String, 分配过的不再分配不再开销,
是不是就能提升性能,更加合理?
所以字符串常量池出来了。

什么东西能存到字符串常量池?

String 对象 通过字面量赋值的,能进去 ,例如 String str=“张三”

再回顾一下 :
什么是字符串字面量?一个字符串字面量就是两个双引号之间的字符序列,形如“张三”、“abc”。

还有就是 通过 String提供的方法 intern() ,可以将字符串丢进去常量池里面。

调用intern方法时,如果池已包含 等于此 string 对象的字符串(通过由使用equals方法),则返回池中的字符串的对象引用。
否则,此Stringobject将添加到池中, 并返回对该String对象的引用。

理解String的不可变性

import org.junit.Test;
//String的使用
public class StringTest {/*String:字符串,使用一对""引起来表示。1.String声明为final的,不可被继承2.String实现了Serializable接口:表示字符串是支持序列化的。实现了Comparable接口:表示String可以比较大小3.String内部定义了final char[] value用于存储字符串数据4.String:代表不可变的字符序列。简称:不可变性。体现:1.当对字符串重新赋值时,需要重写指定内存区域赋值,不能使用原有的value进行赋值。2. 当对现有的字符串进行连接操作时,也需要重新指定内存区域赋值,不能使用原有的value进行赋值。3. 当调用String的replace()方法修改指定字符或字符串时,也需要重新指定内存区域赋值,不能使用原有的value进行赋值。5.通过字面量的方式(区别于new)给一个字符串赋值,此时的字符串值声明在字符串常量池中。6.字符串常量池中是不会存储相同内容的字符串的。*/@Testpublic void test1(){String s1 = "abc";//字面量的定义方式String s2 = "abc";s1 = "hello";System.out.println(s1 == s2);//比较s1和s2的地址值,falseSystem.out.println(s1);//helloSystem.out.println(s2);//abcSystem.out.println("*****************");String s3 = "abc";s3 += "def";System.out.println(s3);//abcdefSystem.out.println(s2);System.out.println("*****************");String s4 = "abc";String s5 = s4.replace('a', 'm');//将a替换成mSystem.out.println(s4);//abcSystem.out.println(s5);//mbc}
}

在这里插入图片描述

String s1 = "abc";
//首次声明,在方法区的字符串常量池中新造abc
//栈中S1指向字符串常量池中的abc
String s2 = "abc";
//声明S2时,会先在常量池中寻找是否有abc,有的话将地址赋给S2
s1 = "hello";
//再次为S1赋值,新造hello,将S1的指针指向hello

String不同实例化方式的对比

String对象的创建

String str = "hello";//本质上this.value = new char[0];
String	s1 = new String();//this.value = original.value;
String	s2 = new String(String original);//this.value = Arrays.copyOf(value, value.length);
String	s3 = new String(char[] a);String	s4 = new String(char[] a,int startIndex,int count);

在这里插入图片描述

  /*String的实例化方式:方式一:通过字面量定义的方式方式二:通过new + 构造器的方式面试题:String s = new String("abc");方式创建对象,在内存中创建了几个对象?两个:一个是堆空间中new结构,另一个是char[]对应的常量池中的数据:"abc"*/@Testpublic void test2(){//通过字面量定义的方式:此时的s1和s2的数据javaEE声明在方法区中的字符串常量池中。String s1 = "javaEE";String s2 = "javaEE";//通过new + 构造器的方式:此时的s3和s4保存的地址值,是数据在堆空间中开辟空间以后对应的地址值。String s3 = new String("javaEE");String s4 = new String("javaEE");System.out.println(s1 == s2);//trueSystem.out.println(s1 == s3);//falseSystem.out.println(s1 == s4);//falseSystem.out.println(s3 == s4);//falseSystem.out.println("***********************");Person p1 = new Person("Tom",12);Person p2 = new Person("Tom",12);System.out.println(p1.name.equals(p2.name));//trueSystem.out.println(p1.name == p2.name);//true//name的地址指向方法区p1.name = "Jerry";System.out.println(p2.name);//Tom}   

在这里插入图片描述

http://www.lryc.cn/news/9854.html

相关文章:

  • 09 OpenCV图形检测
  • 解密Teradata与中国市场“分手”背后的原因!国产数据库能填补空白吗?
  • Bernstein-Vazirani算法
  • 华为OD机试 - 相对开音节 | 备考思路,刷题要点,答疑 【新解法】
  • MyBatis
  • 良好的作息表
  • 【郭东白架构课 模块一:生存法则】01|模块导学:是什么在影响架构活动的成败?
  • webshell免杀之函数与变量玩法
  • 【新解法】华为OD机试 - 去重求和 | 备考思路,刷题要点,答疑,od Base 提供
  • MySQL 服务正在启动.MySQL 服务无法启动.服务没有报告任何错误。请键入 NET HELPMSG 3534 以获得更多的帮助。总结较全 (已解决)
  • 【数据结构与算法】数组2:双指针法 二分法(螺旋矩阵)
  • librtmp优化
  • 数据结构与算法(二):线性表
  • IOS安全区域适配
  • 在Java 中 利用Milo通信库,实现OPCUA客户端,并生成证书
  • 三分钟学会用Vim
  • 编译链接实战(8)认识elf文件格式
  • 新手小白如何入门黑客技术?
  • 【java】Spring Boot --深入SpringBoot注解原理及使用
  • 一文掌握如何对项目进行诊断?【步骤方法和工具】
  • 系统分析师真题2020试卷相关概念二
  • <<Java开发环境配置>>5-MySQL安装教程(绿色版)
  • 空间复杂度与时间复杂度
  • javaEE 初阶 — 延迟应答与捎带应答
  • Twitter账号老被封?一文教会你怎么养号
  • 当遇到国外客户的问题,你解决不了的时候怎么办
  • 算法刷题打卡第93天: 最大的以 1 为边界的正方形
  • python语言基础(最详细版)
  • Java小技能:字符串
  • 2023美赛D题:可持续发展目标