引言
关于Java JDK中内置的一个类:java.lang.String
- String表示字符串类型,属于引用数据类型
- 在java中使用双引号""括起来的都是String对象
- java中规定,双引号括起来的字符串是不可变的,也就是说"abc"整个生命周期内容都不能改变。**为什么不可变:**源代码中String类中有一个byte[]数组,这个byte数组采用了final修饰,因为数组一旦创建长度不可变,并且被final修饰的引用一旦指向某个对象之后,不可再指向其他对象,所以String是不可变的。
String字符串的存储原理
在JDK中双引号括起来的字符串,都是直接存储在方法区的字符串常量池中。原因:字符串使用太频繁,为了保证执行效率。且垃圾回收器不会释放常量。
public static void main(String[] args){
//这两行代码表示底层创建了3个字符串对象,都在字符串常量池中
String s1="abcdef";
String s2="abcdef"+"xy";
}
字符串对象存储在方法区的字符串常量池中,栈中的s1引用保存的地址指向"abcdef",没有引用指向"xy",s2保存的地址指向的是"abcdef"和"xy"拼接后的。以上过程也证明了字符串不可变。
【注】在JDK6.0及之前版本,字符串常量池在方法区中,从7.0版本开始字符串常量池被移到堆中,字符串常量池中存储的是字符串的内存地址,字符串对象还是在堆中。
字符串的比较
String s1="hello";
String s2="hello";
System.out.println(s1==s2);//true
String x=new String("xyz");
String y=new String("xyz");
System.out.println(x==y);//false
System.out.println(x.equals(y));//true,String类中的equals方法
s1和s2指向的都是方法区中同一个"hello",所以s1和s2中保存的内存地址相同。x和y在堆中新建的对象指向的字符串是同一个,但是两个不同的对象,也就对应两个不同的引用,所以x和y不等。
通过上面的案例不难看出字符串对象之间的比较不能用==,有时会达不到想要的效果,应该调用String类中的equals方法,Object类中的equals方法用的也是双等号,String类中重写了该方法。
常用的String类构造方法
String s=new String("");
String s="";
String s=new String(char数组);
String s=new String(char数组,起始下标,长度);
String s=new String(byte数组);
String s=new String(byte数组,起始下标,长度);
String s1="hello world!";//最常用的创建字符串对象方式
byte[] bytes={97,98,99};//97是a,98是b,99是c
char[] chars={'我','是','程','序','员'};
String s2=new String(bytes);
String s3=new String(chars);
System.out.println(s2);//abc,输出一个引用时会自动调用toString()方法
System.out.println(s3);//我是程序员
String s4=new String(bytes,1,2);
String s5=new String(chars,2,3);
System.out.println(s4);//bc
System.out.println(s5);//程序员
String类中的常用方法
char charAt(int index)
返回指定索引处的char值
char c="中国人".charAt(1);
System.out.println(c);//国
int compareTo(String anotherString)
按照字典顺序比较两个字符串
int result="abc".compareTo("abc");
System.out.println(result);//0
int result2="abcd".compareTo("abce");
System.out.println(result2);//-1(小于0) 前小后大
int result3="abce".compareTo("abcd");
System.out.println(result3);//1(大于0) 前大后小
boolean contains(CharSequence s)
判断前面的字符串是否包含后面的子字符串
System.out.println("http://www.baidu.com".contains("https://"));//false
boolean endsWith(String suffix)
判断当前字符串是否以某个字符串结尾boolean equals(Object anObject)
比较两个字符串boolean equalsIgnoreCase(String anotherString)
判断两个字符串是否相等,并且同时忽略大小写byte[] getBytes()
将字符串对象转换成字节数组
byte[] bytes="abc".getBytes();
for(int i=0;i<bytes.length;i++)
System.out.println(bytes[i]);//97 98 99
boolean isEmpty()
判断字符串是否为空,当且仅当length()为0时返回trueint lastIndexOf(String str)
判断某个子字符串在当前字符串中最后一次出现的索引(下标)String replace(CharSequence target,CharSequence replacement)
用 replacement字符串替换原始字符串中所有target子字符串boolean startsWith(String prefix)
判断某个字符串是否以某个子字符串开始String substring(int beginIndex,int endIndex)
从起始下标开始截取字符串,到截止位置前结束(前闭后开[beginIndex,endIndex)),也可以没有endIndex参数char[] toCharArray()
将字符串转换成char数组String toLowerCase()
将字符串中的所有字符转换为小写String toUpperCase()
将字符串中的所有字符转换为大写String trim()
去除字符串前后的空白,不去中间的空白String valueOf()
String中唯一的静态方法,将非字符串转换成字符串