java String类详细讲解及代码演示

String类

在java中没有字符串,String是一个必须使用的程序类,他是java.lang包下的一个实用类,使用时无需导包。在java程序中字符串要求“"”进行定义,在使用中可以用“+”实现字符串连接,接下来我们通过实例和概念详细介绍String类。

1.String类对象实例化

在java中本没有字符串这一数据类型的概念,但是考虑到程序开发的需要,通过设计创造了String类,并且该类的对象可以通过实例化直接赋值的形式进行操作。

String str="Helloworld";
System.out.println(str);//执行程序结果为:Helloworld

在java用“"”声明的内容都是字符串,此段代码是利用直接赋值的形式实现
String类的实例化。
String类属于一个系统类,除了可以以直接赋值的形式进行对象的实例化之外,可以提供对应的构造方法进行对象实例化,String的构造方法为:
public String(String str)。

String str=new String("Helloworld");
System.out.println(str);//执行程序结果为:Helloworld

利用构造方法实例化String类对象更加直观,其最终结果与直接赋值相同,但两者之间有本质区别,下面讲进行逐步讲解。

2.字符串比较

在基本数据类型中进行相等判断可以直接使用java中==运算符来实现,直接进行数值比较。如果在String类中使用双等号,比较的不在是内容,而是字符串的堆内存地址。

String strA="Helloworld";//直接定义字符串
String strB=new String("Helloworld");//构造方法定义字符串
String strC=strB;//引用传递
System.out.println(strA==strB);//比较结果为:false
System.out.println(strA==strC);//比较结果为:false
System.out.println(strB==strC);//比较结果为:true

通过结果发现同一个字符串采用不同的方法进行String类对象实例化后,并不是所有的String类对象的地址数值都是一样的。
首先我们先聊一聊直接赋值的情况:
在这里插入图片描述

从图中可以看出在堆内存中存储的"Helloworld"的一个地址值,然后把这个地址值赋值给栈中的strA中。
在这里插入图片描述
然后用构造方法定义的字符串也是在堆内存中开辟了新内存,把地址值复制给栈中的strB中。

在这里插入图片描述
把strB赋值给strC则是把strB中的地址值传递给strC中而并非在堆内存中开辟新空间,一定要明确这一点。
接下来我们来聊一聊String类中提供的equals方法,只需通过String类实例话对象调用即可,该方法为public boolean equals (Object obj)。

String strA="Helloworld";
String strB=new String("Helloworld");
System.out.println(strA.equals(strB));//程序执行结果为:true

从结果中可以看出equals方式是用来比较字符串内容的的。
总结:1)“==”是java提供的关系运算符,主要功能是用来进行数值的比            较,如果在String对象上表示内存地址数值的比较。
           2)equals()方法是String类提供的一个方法,此方法专门用来进行字符串内容的比较。

3.字符串常量

在程序中常量是不可改变的的量,但在java中可以直接使用“""”进行字符串常量的定义。而这种字符串的常量严格来讲是String类的匿名对象。

String str="Helloworld";
System.out.println("Helloworld".equals(str));//程序运行结果为:true

本程序最大的特点是直接利用字符串"Helloworld"调用equals(),由于equals方法是String类中定义的,而类中普通方法只有实例化对象后才可以调用,那么我们就可以得出结论:字符串常量就是一个匿名对象,而所谓String类直接赋值的操作,实际上就相当于将一个匿名对象设置了一个名字,String类的匿名对象是由系统自动生成的,不再由程序员自己创建。
在这里插入图片描述

4.String两种实例化比较

1)分析直接赋值的对象实例化
在程序中只需要将一个字符串复制给String类的对象就可以实现对象的实例化处理。

String str="Helloworld";

而对同一字符串的多次直接赋值还可以实现堆内存的重用,采用直接复制的方式进行String类对象实例化,在内容相同的情况下不会开辟出新的堆内存空间,而指向已有的堆内存。

String strA="Helloworld";
String strB="Helloworld";
System.out.println(strA==strB);//执行程序结果为true

在这里插入图片描述然后我们简单来聊一聊关于字符串常量池的问题,在JVM底层中有一个字符串对象池,当代码使用直接赋值的方式定义一个String类对象时,会将字符串对象所使用的匿名对象保持在池中,那么将不会开辟出新空间,而是使用已有对象进行引用的分配,从而继续使用。

String strA="Helloworld";
String strB="Helloworld";
System.out.println(strA==strB);//程序运行结果位:true

可以发现strA与strB的地址值是相同的。

2)分析构造方法实例化

String str=new String("Helloworld");

接下来我们来聊一聊构造方法实例化对象的情况,每一个字符串都是一个匿名对象,所以在构造方法实例化对象的时候首先在堆内存中开辟一个空间保存"Helloworld",而后又使用关键字new开辟出另一块堆内存空间,而真正使用的是new开辟出来的堆内存,之前定义的字符串常量开辟的堆内存空间将不会被任何的栈内存说指向,称为垃圾空间,并会被GC回收。所以使用构造方法开辟的字符串对象,实际上会开辟两块空间,其中一块会成为垃圾。
在这里插入图片描述
使用构造方法实例化的String对象是不会进入字符串常量池的。

String strA="Helloworld";
String strB=new String("Helloworld");
System.out.println(strA==strB);//程序运行结果为:false

从结果中可以看出strA与strB的地址值是不同,但是我们可以进行手动导入把构造方法创建出的String类对象保存在池中,所用到的方法为public String intern ()。

String strA="Helloworld";
String strB=new String("Helloworld").intern();;
System.out.println(strA==strB);//程序运行结果为:true

使用这个方法我们就把构造方法实例化的对象手动添加到常量池中。

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

5.字符串常量池

java中使用“’”就可以进行字符串实例化对象的定义,如果处理不当就可以重复开辟堆内存空间,这样必然造成内存的大量浪费。为解决这个问题,在JVM中提供了一个字符串常量池,所有通过直接赋值的对象实例化的String类对象都可以自动保存在次常量池中,以供下次重复使用。在java中字符串常量池分为两种。
1)静态常量池:是指程序在加载的时候会自动将此程序中保存的字符串、普通的常量、类和方法等信息,全部进行分配。

String strA="我爱你中国";
String strB="我爱你"+"中国";
System.out.println(strA==strB);//程序运行结果为true

此段代码用两种方式定义了String类对象,由于实例化strB对象时,所有参与连接的strB字符串都是常量,所以在程序编译时会自动将这些常量组合在一起进行定义。这样strA与strB对象的内容就相同了,且结果是继续使用字符串常量池中提供的内容为strB实例化,不会再开辟新空间。

2)运行时常量池:当程序加载后,有一些字符串内容是通过String类对象的形式保存后再实现字符串连接处理,由于String类内容可以改变,所以此时称为运行时常量池。

String strA="中国";
String strB="我爱你中国";
String strC="我爱你"+strA;
System.out.println(strB==strC);//程序运行结果为:false

此段代码利用了strA定义了要连接字符串的内容,由于strA要运行时才可以确定内容,这样程序就无法知道strA的具体内容,所以strC对象无法从字符串常量池中获取字符串引用。

6. 字符串修改分析

String类对于数据的储存是基于数组实现的,数组本身属于定长的数据类型,一旦声明就不可改变,而所有字符串对象内容的修改都是通过引用额度变化来实现的。

String str="我爱你";
str=str+"中国";
System.out.println(str);//程序运行结果为:我爱你中国

7.String类常用方法

最后我们来聊一聊String类的一些常用方法。
1)根据字符数组创建字符串

char[] charArray={'A','B','C','D'};
String str=new String(charArray);
System.out.println("字符串为:"+str2;//程序运行结果为:ABCD

2)根据字节数组创建字符串

byte[] bypeArray={97,98,99,100};
String str=new String(bypeArray);
System.out.println("字符串位"+str);//程序运行结果为:abcd

3)显示长度 public int length();

  int length="abcedfg".length();
  System.out.println(length);//程序运行结果为:7

4)拼接字符 public String concat(String str);

String str1="Hello";
String str2="World";
String str3=str1.concat(str2);
System.out.println(str3);//程序运行结果为:HelloWorld

5)获取指定位置单个字符 public char charAt(int index);

char chars="Hello".charAt(0);
System.out.println(chars);//程序运行结果为:H

6) 返回指定字符在此字符串中第一次出现处的索引 public int indexOf(String str); 如果存在返回此字符串中第一次出现处的索引,如果不存在则返回-1.

String original="HelloWorld";
int index=original.indexOf("llo");
System.out.println(index);//程序运行结果为:2
System.out.println(original.indexOf("adc"));//程序运行结果为:-1

7)截取字符串 public String subString(int beginIndex);返回一个新的字符串,它是此字符串的一个子字符串,输入的下标是子字符串的起始下标。
public String subString(int beginIndex, int endIndex);这个方法则是截取的起始下标到终止下标的字符串为子字符串。

String original="HelloWorld";
String str1=original.substring(5);
System.out.println(str1);程序运行结果为:World
String str2=original.substring(4, 7);
System.out.println(str2);程序运行结果为:oWo

8)转换为字符数组 public char[ ] toCharArray()

char[] chars="Hello".toCharArray();
System.out.println(chars[0]);程序运行结果为:H
System.out.println(chars.length);程序运行结果为:5

9)字符串内容替换,即 使用指定的字符集将此 String 解码为字节序列,并将结果存储到一个新的字节数组中 ,
public byte[ ] getBytes(String charsetName);

byte[] bytes="abcde".getBytes();
for(int i=0;i<bytes.length;i++){
    System.out.print(bytes[i]+"\t");//程序运行结果为:97 98 99 100 101
}

10)字符串内容替换 public String replace(CharSequence target, CharSequence replacement) ;使用指定的字面值替换序列替换此字符串匹配字面值目标序列的每个子字符串。

String str1="How do you do?";
String str2=str1.replace("o","*");
System.out.println(str1);//程序运行结果为:How do you do?
System.out.println(str2);//程序运行结果为:H*w d* y*u d*?

这用我们就非常详细的聊完了java中String类的所有内容了,如果有什么不足之处欢迎评论区留言。
码字不易,感谢阅读^ ^

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值