Java中String类详细描述

1.String类的实例化方式

  1. 直接赋值
	String str = "hello world";  //str是一个对象的引用,所以“hello world”应该保存在堆内存中
	System.out.println(str);
  1. 传统方法(构造方法)
	//因为String是一个类,所以存在构造方法
	String str = new String("hello world");   //通过构造方法赋值
	System.out.println(str);

2. String字符串比较

  1. 如果有两个int型变量,判断是否相等用==判断
	int x = 10;
	int y = 10;
	System.out.println(x==y);   //true
  1. 如果是两个String进行比较,使用“ == ” 比较,比较的是引用类型的地址
	String str = "hello world";
	String str1 = "hello world";
	String str2 = new String("hello world");

	System.out.println(str == str1);  //true
	System.out.println(str2 == str1); //false
  1. 用equals方法比较字符串的内容
	String str1 = "hello world";
	String str2 = new String("hello world");
	System.out.println(str1.equals(str2));   //true

总结:

  • “ == ”操作符用于比较两个变量的值是否相等,对于基本类型,比较的就是数值大小;对于引用数据类型,比较的是保存的Java中String类详细描述,而不会比较内容
  • 在字符串内容比较时,用String类提供的equals() 方法,区分大小写;使用**equalsIngoreCase()**不区分大小写
  • 当使用直接赋值时,将判断字符串是否存在对象池中,如果有,则直接引用去指向对象池
  • 对象池相当于一个一维数组
  • 如果使用的是构造方法,则新开辟一个空间

3. String的匿名对象(没起名字的对象)

所有的字符串常量 " ",都是String类的匿名对象

	String str1= "hello";
	String str = new String("hello");
	System.out.println(str1.equals(str));
	System.out.println("hello".equals(str));
  • "String str = " hello "; “本质上就是将一个匿名的String类对象设置有名字,而且保存在堆内存中
  • 任何的字符串常量都是String的匿名对象,所以该对象永远不会为空

4. 实例化区别

  1. 采用直接赋值
	String str = "hello";
	String str2 = "hello";
	Stirng str1 = "hello";
	System.out.println(str == str1);   //true
	System.out.println(str == str2);   //true
	System.out.println(str1 == str2);  //true
	//str, str1 , str2三个地址指向同一块空间

JVM底层其实会自动维护一个字符串常量池(对象数组)。如果采用直接赋值实例化对象,先在对象池中寻找是否有指定内容对象,若有,则直接引用;反之,则新创建;其实使用的就是设计模式中的享元模式

  1. 采用构造方法
	String str = new String("hello");
	String str1 = "hello";
	System.out.println(str == str1);  //false 
  • 采用构造方法会开辟两块堆空间
  • 先放的是匿名对象“hello” ,是字符串常量开辟的,然后new一个真正的对象;指向的是new出来的真正的对象,匿名对象那块内存会成为垃圾空间
  • 实例化的对象并不会保存在内存池中
	//入池操作
	//把String对象入池(如果池中有,引用指向它;如果没有,入池加指向)
	String str = "hello";
	String str1 = new String("hello").intern();
	System.out.println(str == str1);   //true

5. 字符串不可变更

  • 字符串一旦定义,不可改变
  • 所有语言对字符串的实现,都是字符数组,数组的最大缺陷就是长度固定。在定义字符串常量时,它的内容不可变
	String str = "hello";
	str = str +" world";
	str += "!!!";
	System.out.println(str);   //hello world!!!
	//4块垃圾空间
	//堆中常量的值无法修改,但是栈的指向一直发生变化

以上字符串的变更,是对字符串对象的变更,而非字符串常量
图示如下:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/mi_zhi_lu/article/details/89219671