详解Java中String类

String类作为Java中三大特殊类之一,一个很重要的类,项目开发中基本都会用到。

实例化方式

1.直接赋值

String str = "Hello World" ; // str是一个对象,那么"Hello Worldt" 保存在堆内存中
System.out.println(str) ;

这种方法最为常用。

2.通过构造方法赋值

String str = new String("Hello World") ;
System.out.println(str) ;

类对象使用构造方法实例化是标准做法。

字符串相等比较

通常,==对于基本类型而言,比较的是数值是否相等。
如下代码,String类对象通过 ==比较:

String str1 = "Hello" ;
String str2 = new String("Hello") ;
System.out.println(str1==str);

结果输出为false。对于String类实例化对象比较相等,可以使用String类提供equals()方法。
例如:

String str1 = "Hello" ;
String str2 = new String("Hello") ;
System.out.println(str1.equals(str2));

结果输出为true。

原因总结如下:
(1)“==”操作符用于比较两个变量的的值是否相等,对于基本类型而言,比较的就是数值的大小;对于引用类型而言,比较的实际上对象中保存的地址是否等待而不会比较内容。
(2)字符串内容比较时需要使用String类提供的equals()方法:str1.equals(str2)。还可以用不区分大小写比较方法:equalsIngoreCase();

String类的匿名对象

在java之中,本身也没有直接提供字符串常量的概念,所有使用 “”定义的内容本质上来讲都是String的匿名对象,即所有的字符串常量都是String类的匿名对象。
例如:

String str1 = "Hello" ;

本质上就是将一个匿名的String类对象设置有名字str1,而且匿名对象一定保存在堆内存中,而str1保存在栈内存中。

在比较两个字符串是否等于特定字符串时,将字符串常量写在equals前面,通过字符串常量来比较(避免用户str输入空,出现空指针异常)。

例如:

String str1 = "Hello" ;
System.out.println(“Hello”.equals(str1));

实例化的区别

1.直接赋值

String str1="hello";
String str2="hello";
String str3="hello";

对应的内存开辟如下:
在这里插入图片描述
从图中分析可以得出并没有开辟新的内存。

这种现象解释如下:

在JVM内部维护一个字符串常量池(对象数组)。若采用直接赋值的方式进行String类的实例化操作,那么JVM将该对象会自动保存到对象池之中。若下一次继续使用直接赋值的方式实例化String对象,先在对象池中寻找是否有指定内容对象,若有,直接引用。否则创建新空间,将新对象入池以供下次使用。

2.构造方法赋值:

对于下面代码

String str = new String("hello")

内存开辟过程如下:
在这里插入图片描述
通过分析可知,如果使用String构造方法就会开辟两块堆内存空间,并且其中一块堆内存将成为垃圾空间。此外,也会对字符串共享产生问题(即新产生的String类引用对象无法入池)。

解决入池操作:String类提供的 public String intern() ;

总结:
1.直接赋值:只会开辟一块堆内存空间,并且该字符串对象可以自动保存在对象池中以供下次使用。
2. 构造方法:会开辟两块堆内存空间,其中一块成为垃圾空间,不会自动保存在对象池中,可以使用intern()方法手工入池。

字符串不可变更

观察下面代码:

String str1 = "Hello" ;
str1= str1 + " World" ;
str1 += "!!!" ;
System.out.println(str1); // Hello World!!!

观察下图:
在这里插入图片描述
从图中可以发现字符串上没有发生任何变化,但是字符串对象的引用一直在改变,而且会形成大量的垃圾空间。

所有的语言对于字符串的底层实现,都是字符数组,数组的最大缺陷就是长度固定。在定义字符串常量时,它的内容不可改变。所以开发中尽量不要出现上面的代码。

StringBuffer类与StringBulider类

两个类为了方便进行字符串内容的修改,两个类提供了同样的的构造方法和常用方法,但是StringBuffer采用同步处理,属于线程安全操作;而StringBuilder采用异步处理,属于线程不安全操作。这里以StringBuffer类为例讲解。

1.StringBuffer类的append()方法

public synchronized StringBuffer append(各种数据类型 b)

在StringBuffer类中使用append()方法进行字符串连接。

例如:

public class test{
 public static void main(String[] args){
        //StringBuffer类测试
       StringBuffer str=new StringBuffer();
       //堆内存上进行连接
       str.append("hello").append("aduduo");
       System.out.println(str);
    }
}

String和StringBuffer类不能直接转换。如果要想互相转换,可以采用如下原则:

(1) StringBuffer转为String:
a.通过StringBuffer的构造方法:
public StringBuffer(String str);
b.通过 StringBuffer append (String str);

(2) String转为 StringBuffer:
调用StringBuffer的toString的方法;

2.StringBuffer类的其它方法:
(1)字符串反转

public synchronized StringBuffer reverse()

(2)删除指定范围的数据

public synchronized StringBuffer delete(int start, int end)

(3)插入数据

public synchronized StringBuffer insert(int offset, 各种数据类型 b)

3.请解释String、StringBuffer、StringBuilder的区别:

(1)String的内容不可修改,StringBuffer与StringBuilder的内容可以修改.;
(2)StringBuffer采用同步处理,属于线程安全操作,性能较低;而StringBuilder采用异步处理,属于线程不安全操作,性能较高;
(3)普遍场景下,推荐使用StringBulider,当String对象使用“+”进行字符串拼接时,javac编译器会将String对象变为StringBuilder类对象而后调用appen()方法来修改字符串内容,减少无用空间的开辟。拼接完成后,通过toString()方法转化为String类对象返回;
字符串与基本数据类型转换

String类型与基本数据类型转换

1.String类型变为基本数据类型

(1)String变为int 类型(Integer类):public static int parseInt(String s) throws NumberFormatException;
(2)String变为double类型(Double类):public static double parseDouble(String s) throws NumberFormatException;
(3) String变为Boolean类型(Boolean类):public static boolean parseBoolean(String s);

当String类对象中包含了非数字,在运行时会抛出NumberFormatException异常。

2基本数据类型转换变为变为String类型:

(1)通过“+”方法;
(2)通过String类的构造方法;
(3)推荐:使用String.valueOf(所有基本类型);

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值