String的两种实例化方式
直接赋值和传统实例化:
public class Stringob
{
public static void main(String[] args)
{
String str1="hello"; //直接赋值 str是一个对象,那么"hello" 就应该保存在堆内存中,String类可以直接赋值,JDK所做的简化
String str2=new String("hello"); //传统赋值 用new
System.out.println(str1); //hello
System.out.println(str2); //hello
}
}
字符串相等比较
1.如果是==
用==比较:
String str1 = "Hello" ;
String str = new String("Hello") ;
System.out.println(str1==str); // false ==比较的是地址
2.用equals
public boolean equals(String anotherString); 是成员方法, 通过对象调用
// /字符串比较
public class Stringob
{
public static void main(String[] args)
{
String str=null; //假设有由用户输入为空
//System.out.println(str.equals("hello")); //报错:NullPointerException
System.out.println("hello".equals(str)); //推荐使用此种比较方法,将特定字符串"hello"写在前边
}
}
小建议:如果要判断用户输入的字符串时是否等同于特定字符串,一定要将特定字符串(String常量,任何的字符串常量都是String的匿名对象,所以该对象不为null)写在前面,避免空指针异常(NullPointerException)
面试题:==和equals的区别:
==比较两个字符串的地址,equals是比较两个字符串内容。
对象池:
JVM底层会自动维护一个字符串的对象池,如果现在采用直接赋值的形式进行String的对象实例化,该对象会自动保存在这个对象池中。如果下次继续使用直接赋值的模式声明String对象,此时对象池中如果有指定内容,则直接引用;如果没有,则开辟新的堆空间后将其保存在对象池中下次使用。
public class Stringob
{
public static void main(String[] args)
{
String str1="hello";
String str2="hello";
String str3="hello";
System.out.println(str1==str2); //true
System.out.println(str2==str3); //true
//"hello"是直接赋值,已经在对象池,所以str2和str3也指向str1指向的内容
String str4=new String("hello");
System.out.println(str1==str4); //false 新开的空间不在对象池
//手动入池 (本地方法):
//public native String intern( );(本地方法,没有方法体)
String str5=new String("hello").intern(); //手动入池
System.out.println(str5==str1); //true 因为str5入池
}
}
面试题:String两种实例化区别:
- 直接赋值:只会开辟一块堆内存空间,并且该字符串对象可以自动保存在对象池中以供下次使用。
- 构造方法:会开辟两块堆内存空间,其中一块成为垃圾空间,不会自动保存在对象池中,可以使用intern()方法手工入池。
(比如:String str=new String(“hello”) , "hello"成为垃圾空间,新new的空间str指向。)
字符串常量不可变更
所有的语言对于字符串的底层实现,都是字符数组,数组的最大缺陷就是长度固定。在定义字符串常量时,它的内容不可改变。 即字符串一旦定义后不可改变(字符串内容不可变,但指向即引用可变)
现在看一组实例:
public class Stringob
{
public static void main(String[] args)
{
String str="hello";
str = str + " world";
str+="!!!";
System.out.println(str); //hello world!!! 字符串内容不可变,但引用可变
}
}
注:只要对象不存在,就会有一段新堆空间。原则:字符串不能改变太多(+=操作尽量少)
如:String str=“hello”
str+=“world”, //现在str指向"hello world", 有两个垃圾空间 “hello”和"world"