Java——String类使用详解(实例化、字符串比较、匿名对象、两种实例化方法的区别)

举报
Winter_world 发表于 2021/09/28 23:31:35 2021/09/28
【摘要】 目录 1、String类的两种实例化方式 2、字符串比较 3、String匿名对象 4、String类两种实例化的区别 5、字符串声明后不可改变 6、结论 1、String类的两种实例化方式 String类不是一个基本数据类型,它是一个类,这个类设计过程种加入了Java的特殊支持,其实例化形式有两种形式: 直接赋值:...

目录

1、String类的两种实例化方式

2、字符串比较

3、String匿名对象

4、String类两种实例化的区别

5、字符串声明后不可改变

6、结论


1、String类的两种实例化方式

String类不是一个基本数据类型,它是一个类,这个类设计过程种加入了Java的特殊支持,其实例化形式有两种形式:

  • 直接赋值: String 对象 = “内容”;
  • 构造方法:public String (String s);

以上两种方式均可用,但是具体还是有一些区别。

2、字符串比较

对于int类型数据,两个直接赋值的变量使用“ ==”可以进行想等判断,但是对于String类型数据却不能这样直接比较,见如下范例:


  
  1. String stra = "hello";
  2. String strb = new String("hello");
  3. String strc = strb; //引用传递
  4. System.out.println(stra==strb); //false
  5. System.out.println(strb==strc); //true
  6. System.out.println(stra==strc); //false

以上三个字符串内容一致,但是使用==比较,发现有的比较结果却是false。实际上这里的比较 实际上比较的是两个对象(任意的引用类型)的堆内存的地址数值,属于数值内容的比较,并非堆内存种保存内容的比较。

若要对两个字符串进行比较,可以使用String类中的一个方法:public boolean equals(String str)。


  
  1. String stra = "hello";
  2. String strb = new String("hello");
  3. String strc = strb; //引用传递
  4. System.out.println(stra.equals(strb)); //true
  5. System.out.println(strb.equals(strc)); //true
  6. System.out.println(stra.equals(strc)); //true

【经典问题】String 比较中 == 与equals的区别?

  • "=="是关系运算符,可以进行数值比较,如果用在String上,表示对象内存地址数值比较,不能比较内容。
  • equals是String类自己定义的方法,用于进行字符串内容的比较。

3、String匿名对象

任何编程语言都不会提供字符串数据类型,字符串在很多语言中使用字符数组,Java中为解决这个问题,提供了String类,Java里面也提供双引号声明的数据,这些数据不是普通的变量,而是属于String类的匿名对象。

【举例】:验证匿名对象


  
  1. String str = "hello";
  2. System.out.printlin("hello".equals(str)); //true

开发中,在比较字符串内容是否相同时,一般将常量写在前面,这样避免equals前面的字符串内容为null,equals方法本身具有null判断的功能。

4、String类两种实例化的区别

由第一节中 的内容可知,对于String示例化方式有两种,到底该使用哪种,两种的区别是什么?

1)分析String类对象直接示例化的形式

【直接赋值】使用 的是最多的:


  
  1. String str = "hello"
  2. System.out.println(str);

开辟一块堆内存空间,且一块栈内存直接指向该堆内存空间。

【继续观察直接赋值】


  
  1. String stra = "hello";
  2. String strb = "hello";
  3. String strc = "nihao";
  4. System.out.println(stra==strb); //true
  5. System.out.println(strb==strc); //false
  6. System.out.println(stra==strc); //false

很奇怪,是不是和前面分析的不太一样,其实还是一样的,只不过有一点需要注意,stra和strb指向的内容是相同的,不会重复开辟堆内存空间。这里涉及到对象池的概念。

关于对象池(Object Pool):Java设计过程中,为方便用户开发,针对几个特殊的类使用了共享设计的思路,String就属于其中一个类,这种设计思路是Java自己的支持,只针对于直接赋值的情况。

在使用直接赋值实例化String类对象操作中,字符串内容定义后实际上会自动保存在一个对象池之中,而后,若有其他 的字符串对象也采用直接赋值的形式,且内容与之前的完全相同,则不会开辟新的堆内存空间,而是通过对象池,找到已有的堆内存空间地址,直接引用,所以会出现如上范例的结果。

1)利用构造方法实例化对象


  
  1. String str = new String("hello");
  2. System.out.println(str);

由以上内存分析可以发现,通过构造方法进行实例化对象操作,最终会产生两块堆内存,其中一块是垃圾空间。

【举例】:没有入池的问题


  
  1. String stra = new String("hello"); //构造方法
  2. String strb = "hello"; //直接赋值
  3. System.out.println(str);//false

使用构造方法进行String类对象实例化,产生的对象不会保存在对象池中,此对象无法重用。若用户需要让这个对象入池,只能通过手工入池方法完成:

手工入池:public String intern().


  
  1. String stra = new String("hello").intern; //构造方法
  2. String strb = "hello"; //直接赋值
  3. System.out.println(str);//此处结果为true

【经典问题】:String类两种对象的实例化区别是什么?

  • 直接赋值(String str ="字符串"):仅开辟一块堆内存空间,且对象可以自动入池以共其他对象重复使用;
  • 构造方法(String str = new String("字符串")):开辟两块堆内存空间,且有一块会成为垃圾,产生的对象不会自动入池,需要使用intern()方法手动入池。

5、字符串声明后不可改变

【举例】:


  
  1. String str = "Hello ";
  2. str += "World ";
  3. str = str+ "!!!";
  4. System.out.println(str); //Hello World !!!

 进行内存分析可以发现,以上程序操作都是String类对象的引用发生改变,而字符串的内容实质上根本没有发生改变,这样操作形成了很多垃圾空间,因此,在开发中,一定禁止循环修改String。后续会讲到StringBuffer和StringBuilder,可以用于循环修改。

6、结论

  • 1)String开发中都使用直接赋值,并且不要频繁修改,因为会产生垃圾空间;
  • 2)字符串内容比较时用equals()方法。

 

作于202003202245,已归档

———————————————————————————————————

本文为博主原创文章,转载请注明出处!

若本文对您有帮助,轻抬您发财的小手,关注/评论/点赞/收藏,就是对我最大的支持!

祝君升职加薪,鹏程万里!

文章来源: winter.blog.csdn.net,作者:Winter_world,版权归原作者所有,如需转载,请联系作者。

原文链接:winter.blog.csdn.net/article/details/105162900

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。