JAVA——特殊类(1)——String类(1)

(一)两种实例化方法

(二)字符串的相等比较

(三)String的匿名对象

(四)两种实例化的区别

(五)字符串不可改变

(一)两种实例化方法

  1. 直接赋值
    即使用字符串常量直径二初始化一个String对象。
    举例如下:
String str1 = "hello";//直接赋值
System.out.println(str1);
//此时应该输出 hello
  1. 构造法
    即使用String的构造方法初始化字符串对象。
    举例如下:
String str1 = new String("hello");//堆空间上开辟两个内存块
System.out.println(str1);
//此处输出hello

(二)字符串的相等比较

  • 基本数据类型比较——使用 ==

  • 引用数据类型比较——使用 equals 关键字
    比如字符串str1 和 str2 比较,str1.equals(str2)

  • == 是用来进行数值比较的;若使用 == 用来比较字符串,则比较的是字符串对象的内存地址比较;

  • equals 则是进行字符串对象的 内容比较。

举例如下:
(1)基本数据类型可以使用 == 比较

public class TestString11_20{
	public static void main(String[] args){
		int num1 = 3;
		int num2 = 3;
		System.out.println(num1 == num2);
		//此时结果为 true
	}
}

运行结果如下:
在这里插入图片描述

(2)引用数据类型不可以使用 == 比较

public class TestString11_20{
	public static void main(String[] args){
		String str1 = "hello"; //匿名对象
        String str2 = new String("hello");
		System.out.println(str1 == str2);
//虽然str1 与str2内容一样,但此处结果为false,说明str1 与 str2 不相等
//此时str1 与 str2 比较的是内存地址的值而并非内容
	}
}

运行结果如下:
在这里插入图片描述(3)字符串比较使用equals

public class TestString11_20{
	public static void main(String[] args){
		String str1 = "hello"; //匿名对象
        String str2 = new String("hello");
		System.out.println("str1  equals  str2  :"+str1.equals(str2));
	}
}

运行结果如下:
在这里插入图片描述

(三)String的匿名对象

String str1 = “hello”;
hello即匿名对象,此时只不过给匿名对象起了名字 str1.
注意:
如果要判断用户输入的字符串是否等同于特定字符串,一定要将特定字符串写 在前面。
(即比较时将匿名对象卸载前面。)
匿名对象.equals(用户输入的字符串对象)。


原因:防止用户输入的字符串为空。出现 NullPointerException 错误。

举例如下:

public class TestString11_20{
	public static void main(String[] args){
		String str1 = null; 
        String str2 = "hello";
		System.out.println("str1  equals  str2  :"+str1.equals(str2));
	}
}

运行结果会报错:
在这里插入图片描述应该严格将匿名对象卸载前面,这样就不会报错:

public class TestString11_20{
	public static void main(String[] args){
		String str1 = null; 
        String str2 = "hello";
		System.out.println("str1  equals  str2  :"+str2.equals(str1));
	}
}

运行结果如下:
在这里插入图片描述

(四)实例化的区别

String类的设计使用了共享设计模式
在JVM底层实际上会自动维护一个对象池(字符串对象池),如果现在采用了直接赋值的模式进行String类的对象 实例化操作,那么该实例化对象(字符串内容)将自动保存到这个对象池之中。如果下次继续使用直接赋值的模式 声明String类对象,此时对象池之中如若有指定内容,将直接进行引用;如若没有,则开辟新的字符串对象而后将 其保存在对象池之中以供下次使用

  • 使用直接赋值法赋值的时候,使用的是共享池,如在堆内存中有一块内存为 hello,若 str1,str2,,,等的对象内容都是hello,则它们指向同一块堆内存,所以使用 == 比较的时候,它们的内存地址的值都相等。
  • 使用构造方法的时候,在堆内存中本身就存在一块内存,内容为hello,使用构造方法是将该内容拷贝一份,放在另外一块堆内存上。所以说使用构造方法的时候,是开辟了两个内存块。所以内存地址的值已经发生变化。
    (1)直接赋值:只会开辟一块堆内存空间,并且该字符串对象可以自动保存在对象池中以供下次使用。


    (2) 构造方法:会开辟两块堆内存空间,其中一块成为垃圾空间,不会自动保存在对象池中,可以使用 intern()方法手工入池。


    (1)直接赋值法
public class TestString11_20{
	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
        System.out.println(str1 == str3);//true
	}
}

运行结果如下:
在这里插入图片描述

(2)采用构造方法

public class TestString11_20{
	public static void main(String[] args){
		String str1 = "hello"; 
        String str4 = new String("hello");//堆空间上开辟两个内存块
        System.out.println(str1 == str4);//false
	}
}

运行结果如下:
在这里插入图片描述
使用构造方法时,String提供方法入池操作:
public String intern() ;

public class TestString11_20{
	public static void main(String[] args){
        String str4 = new String("hello").intern();//入池操作
        //String str4 = new String();
        //str4 = str4.intern();
        //该语句等价于上面的入池语句
		String str1 = "hello"; 
        System.out.println(str1 == str4);//false
	}
}

运行结果如下:
在这里插入图片描述

(五)字符串不可改变

字符串一旦定义不可改变。
即字符串本身不发生改变,是字符串对象的引用一直在变化。
如果对字符串进行修改,会创建新的字符串对象。
不要在循环里进行 大量的字符串拼接。

猜你喜欢

转载自blog.csdn.net/xmfjmcwf/article/details/84313957