JAVA基础(String类)
一.String 对象内存
1.为什么String 的变量(对象)输出不是地址?
因为所有的类继承Object类,所以单独输出String一个对象的时候,他会调用Object.toString,打印出来的就是一串表达地址的字符串,最后调用的toString。
然而我们的String类里重写了toString(),它返回的是String自己,String是什么呢,String其实就是字符数组(),它内部封装了一个字符数组,所以打印字符串就是打印字符数组,而不是地址
关于Java中String内存地址的问题。
在创建String类型的变量的时候建议使用直接赋值的方法去创建对象,在多个变量使用同一个字符串的时候,如果采用new 的方法的话,创建出来的对象是放在栈内存中,每个变量都会开辟出新的内存空间来完成储存,不管字符串是否一致。如果采用直接赋值的方式的话,字符串会放在常量池当中,不管创建多少个对象,都是引用的常量池的那个字符串,
(图片来自:https://www.pianshen.com/article/80721423184/)
两种方法相比较下来,直接赋值更加节省内存空间。
(补充:关于java String常量的存储位置https://www.cnblogs.com/zhaohongtian/p/6801302.html)
扩展:Java中String str=“hello”;与String str=new String(“hello”);为对象赋值的区别。
1、一个字符串就是一个String类的匿名对象为解释上面问题,我们首先要知道的是:一个字符串就是String类的匿名对象,其有自己的堆内存空间(对象池)。
2、String stra=“hello”;该直接赋值本质是将一个开辟好的堆内存空间的使用权交给了对象stra,也可以说对象stra指向了保存有“hello”的堆内存空间。(匿名对象’‘hello’'自动入池)
----------------------------------( 图1)--------------------------------------
3、String str=new String(“hello”);该方法是重新开辟一个新的堆内存空间并将“hello”保存进去。("hello"并没有入池,可以进行手动入池)
----------------------------------( 图2)--------------------------------------
使用构造方法实例化对象,其所指内容不会保存在对象池中,因为new开辟了新的堆内存(见上图1,2,下图1),如果想要入池可以使用intern()函数手动入池(见下图2)
----------------------------------( 图1)--------------------------------------
----------------------------------( 图2)--------------------------------------
4、两种方法的比较:直接赋值不需要开辟新的内存,而是直接获得"hello"对象内存的使用权,且以后声明"hello"对象都不会开辟新的内存空间,而是直接引用;而通过new String()方法赋值需要开辟新的内存空间。
2.String类的常量是String类的匿名对象(匿名对象可以调用方法)
再次验证匿名对象的存在:
二.String字符串内容一旦声明不可改,通过String对象引用传递,使得对象指向改变,但同时产生大量的垃圾空间
以下例子典型说明了String字符串内容一旦声明不可改
package String类;
public class TestString {
public static void main(String[] args) {
String stra = "hello ";
fun(stra);
System.out.println(stra);
}
public static void fun(String temp)
{
temp = "world";
}
}
三.String类的各种方法
1.字符串与字符数组的相互转化
package String类;
public class TestString {
public static void main(String[] args) {
//字符串转化为字符数组
String stra = "hello";
char data[] = stra.toCharArray();
for (int i = 0; i < data.length; i++) {
System.out.print(data[i]+",");
}
//字符数组转化为字符串
char data2[]={'w','o','r','l','d'};
//将字符数组全部转化字符串
String strb = new String(data2);
//将字符数组部分转化字符串
//offset:开始索引,count:从开始索引往后转化的个数
String strc = new String(data2,1,3);
System.out.println(strb);
System.out.println(strc);
}
}
2.字符串比较函数
package String类;
public class TestString {
public static void main(String[] args) {
String stra = "hello";
String strb = "Hello";
//字符串比较equals()区分大小写,equalsIgnoreCase()不区分
System.out.println(stra.equals(strb));
System.out.println(stra.equalsIgnoreCase(strb));
//compareTo比较两个字符串的大小,从第一个字符按照ASCLL码相减
// 大于零->stra大,小于零->strb大,等于零->一样大,内容一样
System.out.println(stra.compareTo(strb));
}
}
3.字符串查找函数
package String类;
public class TestString {
public static void main(String[] args) {
String stra = "hello";
String strb = "he";
//判断子字符串是否存在(字符串中任意连续的字符组成子字符串)
System.out.println(stra.contains(strb));
//从前往后查找子字符串的位置,找到返回子字符串首字母的索引,找不到返回-1
System.out.println(stra.indexOf(strb));
//从指定位置从前往后查找子字符串的位置,找到返回子字符串首字母的索引,找不到返回-1
System.out.println(stra.indexOf(strb,0));
//从后往前查找子字符串的位置,找到返回子字符串首字母的索引,找不到返回-1
System.out.println(stra.lastIndexOf(strb));
//从指定位置从后往前查找子字符串的位置,找到返回子字符串首字母的索引,找不到返回-1
System.out.println(stra.lastIndexOf(strb,3));
//判断是否以指定的字符串开头
System.out.println(stra.startsWith(strb));
//从指定位置判断是否以指定的字符串开头
System.out.println(stra.startsWith(strb,0));
//判断是否以指定的字符串结尾
System.out.println(stra.endsWith(strb));
}
}
4.字符串替换函数
package String类;
public class TestString {
public static void main(String[] args) {
String stra = "he..o";
//将 "."全部替换成 "l",需要加上"\\"转义--->准备字符"."
//如果是普通的字母替换不需要加"\\"
String strb = stra.replaceAll("\\.","l");
//首个替换,只替换第一个即可
String strc =stra.replaceFirst("\\.","l");
System.out.println(strb);
System.out.println(strc);
}
}
5.字符串截取函数
package String类;
public class TestString {
public static void main(String[] args) {
String stra = "hello";
//字符串截取从指定索引-->结束
String strb = stra.substring(2);
//字符串截取从指定开始索引--->指定结束索引
String strc =stra.substring(1,4);
System.out.println(strb);
System.out.println(strc);
}
}
6.字符串分割函数(分割成一个个字符串数组)
package String类;
public class TestString {
public static void main(String[] args) {
String stra = "aaa:10|bbb:10|ccc:20";
//当出现正则标记时如 "." "|" 进行分割时需要加上 "\\"转义字符
String result[] = stra.split("\\|");
for (int i = 0; i < result.length; i++) {
String temp[] = result[i].split(":");
System.out.println("姓名:"+temp[0]+" 年龄:"+temp[1]);
}
}
}
7.字符串的其他函数
package String类;
public class TestString {
public static void main(String[] args) {
String stra = " ";
//得到字符串的长度,这里区分 数组名.length 与 字符串名.length()
System.out.println(stra.length());
//判断字符串的长度是否为零
System.out.println(stra.isEmpty());
}
}
本文地址:https://blog.csdn.net/weixin_43563049/article/details/107574238