String类

mac2024-01-25  37

创建字符串

//方式1 String str1 = “Hello world”; //方式2 String str2 = new String("Hello world") ; //方式3 char[] array = {'a','b','c'}; String str3 = new String(array);

解释:

//String是引用类型 String str = “Hello”;

这样的代码内存布局如下: **引用解释:**引用类似于C语言中的指针,只是在栈上开辟了一小块内存空间保存一个地址,但和指针不同,指针可以进行各种数字运算(如:指针+1),但引用不能。除此我们也可以将引用想象成一个标签,“贴”到一个对象上,一个对象可以贴一个,也可以贴多个,如果一个对象上一个标签都没有,这个对象就会被JVM当成垃圾对象回收掉。 java中数组,String,以及自定义类型都是引用类型。

下面我们来看下面的代码及内存布局

String str1 = "Hello"; String str2 = str1; //str1和str2指向同一个对象

在上面的基础上我们再来看下面的代码

str1 = "world"; System.out.println(str2); // 执行结果 :Hello //str1只是指向了一个新的string类对象,但是str2的指向还是没有改变。

字符串比较相等

两个int 型的变量可以用==判断其是否相等。但是String呢? 代码1:

String str1 = "Hello"; String str2 = "Hello"; System.out.println(str1 == str2); // 执行结果:true //这个代码中str1和str2指向同一个对象

但是下面的代码比较就出现了问题 代码2:

String str1 = new String("Hello"); String str2 = new String("Hello"); System.out.println(str1 == str2); // 执行结果:false //这种方式创建的String对象相当于在堆上另外开辟了空间来存储“Hello”内容,内存中存了两份“Hello”。str1指向一份“Hello”,str2指向一份“Hello”。

所以Java中比较字符串的内容是否相等,要采用equals方法

String str1 = new String("Hello"); String str2 = new String("Hello"); System.out.println(str1.equals(str2)); // 执行结果:true

equals使用注意事项:

String str = new String("Hello"); // 方式一 System.out.println(str.equals("Hello")); // 方式二 System.out.println("Hello".equals(str)); //“Hello”这样的字面值常量,本质上也是一个String对象, 可以用equals等String对象的方法。

字符常量池

(1)直接赋值

String str1 = "hello" ; String str2 = "hello" ; String str3 = "hello" ; System.out.println(str1 == str2); //true System.out.println(str1 == str3); //true System.out.println(str2 == str3); //true

从上图我们可以看到并没有开辟新的堆内存空间。 这是String类的设计使用了共享设计模式。 **解释:**如果现在采用了直接赋值的模式进行String类的对象实例化操作,那么该实例化对象(字符串内容)将自动保存到这个对象池之中。如果下次继续使用直接赋值的模式声明String类对象,此时对象池之中如若有指定内容,将直接进行引用;如若没有,则开辟新的字符串对象而后将其保存在对象池之中以供下次使用。 (2)采用构造方法

String str = new String ("Hello");

这样做有两个缺点: a. 使用String构造方法会开辟两块堆内存,并且其中一块堆内存会成为垃圾空间(字符常量“Hello”也是一个匿名对象,用了一次之后就不在使用了,就会成为垃圾空间,被JVM自动回收掉)。 b.同一个字符串可能会被存储多次,比较浪费空间。 我们可以使用String的intern方法手动把String对象加入字符串常量池中。

// 该字符串常量并没有保存在对象池之中 String str1 = new String("hello") ; String str2 = "hello" ; System.out.println(str1 == str2); // 执行结果:false String str1 = new String("hello").intern() ; String str2 = "hello" ; System.out.println(str1 == str2); // 执行结果:true

字符串的不可变性

字符串是一种不可变对象,它的内容不可改变。 String类的内部实现是基于Char[]来实现的,但是String类并没有提供set方法之类的来修改内部的字符串数组。

String str = "hello" ; str = str + " world" ; str += "!!!" ; System.out.println(str); // 执行结果:hello world!!!

上面的代码表面上改了字符串,其实并不是。内存变化如下 就我们看到str的结果改变了,但并不是String对象本身发生改变,而是str引用到了其他对象。

如果需要修改字符串,则需要借助原字符串,创建新的字符串。代码如下:

String str = 'Hello"; str = "h" + str.substring(1); System.out.println(str); //执行结果:hello
最新回复(0)