在java中,使用String类型来表示字符串。String类使用final关键字修饰,即该类不可被继承,String类中封装了丰富的用于对字符串进行操作的相关方法。底层使用字符数组实现。
//JDK中String类String类型为引用类型,由于其使用频繁,因此java中可以使用类似于基本类型的方式创建String类对象(内存中不同)。以下为创建String类的两种方式
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence
{
private final char value[];
...
}
public static void main(String[] args) {使用String s="hello"这种方式创建String类型变量时,java虚拟机会现在常量池中寻找有没有存在的"hello"字符常量,如果存在直接使用,如若不存在,则在常量池中创建新的"hello"常量。最后将栈中的引用s指向该字符串常量。
//字面量方式赋值,String引用类型可使用基本数据类型的方式创建
String s="helloworld";
String s2=new String("helloworld");
}
使用String s=new String("hello");这种方式创建对象时,jvm不仅会在字符串常量池中创建"hello"字符串常量,而且会在堆空间中new一个对象指向该常量(所有new出来的对象都在堆空间中分配),最后栈空间的引用s指向堆空间new出来的对象。等于创建了两个对象,所以推荐使用String s="hello";这种方式创建String对象性能会好一点。
以下是由此得出的字符串间==比较的结果,==比较的是引用的地址是否相同。
@Test再看下面两个可能会引起疑惑的例子
public void test2(){
//字面量创建,先去常量池查找是否有该字符串对象.
String s1="123abc";
String s2="123abc";
System.out.println(s1==s2);//true
//new 一定会创建新的对象
String s4=new String("123abc");
System.out.println(s1==s4);//false
}
@Test public void test03(){ String s1="123abc"; String s5="123"+"abc";//编译期 如果发现一个计算表达式,两边全是字面量,自动计算.如果计算表达式含变量,不运算, System.out.println(s1==s5);//true String s6="123"; String s7=s6+"abc"; System.out.println(s1==s7);//false }在创建String s5="123"+"abc";时,编译期 如果发现一个计算表达式,两边全是字面量,会自动计算。也就是说该行代码等价于String s5="123abc"。
但是.如果计算表达式含变量,编译期则不会运算,s7对象创建的过程实际等价于以下的过程:
String s7=new StringBuilder(s6).append("abc").toString();所以s1==s7结果为false
String类的对象是不可变对象,即:String对象内容不可改变,若改变 字符串的内容一定是创建了新的对象。
@Test
public void test01(){
String s1="12a";
String s2=s1;
System.out.println(s1==s2);//true
s1=s1+"b";
//String为不可变对象 当String里内容改变时,实为创建新的对象,s1的引用地址改变
System.out.println(s1==s2);//false
}
String重写的equals()方法则用来比较两个字符串的具体内容是否相同。使用equals()方法时的一个注意点,使用字符串 常量.equals(String str)的方式可以有效避免空指针异常。
/**后面的文章中再接着介绍String中的相关方法。
* @author zc
*/
@Test
public void testEquals(String str){
String s="zc";
if("zc".equals(str)){
System.out.println("");
}
}