> 地理
stig对象的特点(stig对象存在哪里)
导语:谈谈你对String对象的了解
在Java编程中字符串应用最广泛,Java提供了String类创建和操作字符串。String的值是不可变的,这就导致了String每次操作字符串对象都会生成新的对象,这样就会导致效率低下,而且大量浪费珍贵且有限的内存空间。
String是被final修饰的类,不能被继承,不能被修改;String实现了Serializable和Comparable 接口,表示String支持序列化和可以比较大小;String底层是通过char类型的数据实现的,如下图String类源码:
String类是不可变类,一旦创建一个String对象,包含在这个对象中字符序列是不可改变的,直到这个对象被销毁。
举个列子来看一下内存空间有什么变化:
// 通过直接赋值的形式进行实例化String name = &34;;name = &34;;// 输出结果:虚竹System.out.println(name);// 通过构造方法实例化String类对象String username = new String(&34;);// 输出结果:段誉System.out.println(username);
来StringTest.class看一下源码:
public class com.saq.day01.main.StringTest minor version: 0 major version: 49 flags: (0x0021) ACC_PUBLIC, ACC_SUPER this_class: 3 // java/lang/Object interfaces: 0, fields: 0, methods: 2, attributes: 1Constant pool: 2 // com/saq/day01/main/StringTest 3 = Class 4 = Utf8 java/lang/Object 6 = Utf8 ()V 8 = Methodref 9 // java/lang/Object.&34;:()V 5:34;<init>&10 = Utf8 LineNumberTable 12 = Utf8 this 14 = Utf8 main 16 = String 17 = Utf8 乔峰 19 // 虚竹 20 = Fieldref 23 // java/lang/System.out:Ljava/io/PrintStream; 22 // java/lang/System 23 = NameAndType 25 // out:Ljava/io/PrintStream; 25 = Utf8 Ljava/io/PrintStream; 27.27 = Class 28 = Utf8 java/io/PrintStream 30:30 = Utf8 println 32 = Class 33 = Utf8 java/lang/String 35 // 段誉 36 = Methodref 37 // java/lang/String.&34;:(Ljava/lang/String;)V 5:34;<init>&38 = Utf8 args 40 = Utf8 name 42 = Utf8 username 44 = Utf8 StringTest.java{ public com.saq.day01.main.StringTest(); descriptor: ()V flags: (0x0001) ACC_PUBLIC Code: stack=1, locals=1, args_size=1 0: aload_0 1: invokespecial 34;<init>&16 // String 乔峰 2: astore_1 3: ldc 20 // Field java/lang/System.out:Ljava/io/PrintStream; 9: aload_1 10: invokevirtual 32 // class java/lang/String 16: dup 17: ldc 36 // Method java/lang/String.&34;:(Ljava/lang/String;)V 22: astore_2 23: getstatic 26 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 30: return LineNumberTable: line 10: 0 line 11: 3 line 13: 6 line 15: 13 line 17: 23 line 18: 30 LocalVariableTable: Start Length Slot Name Signature 0 31 0 args [Ljava/lang/String; 3 28 1 name Ljava/lang/String; 23 8 2 username Ljava/lang/String;}
从文件中可以看出字符串常量池(Constant pool)有两个对象。可以看出,再次给name对象赋值时,并不是对原来堆中实例对象进行重新赋值,而是生成一个新的实例对象,并且指向“虚竹”这个字符串,name则指向新生成的实例对象,之前的实例对象仍然存在,如果没有被再次引用,则会被垃圾回收。
String类对象实例化的方式有两种:
1.通过直接赋值的形式进行实例化
String name = &34;;
2.通过构造方法实例化String类对象
String name = new String(&34;);
两种实例化String类对象虽然结果一样,但是本质上有很多区别,通过直接赋值的方式为字符串赋值时,此时的字符串存储在方法区的字符串常量池中;通过构造器方式实例化字符串时,字符串对象存储在堆中,但是字符串的值仍然存储在方法区的常量池中。
本文内容由小茹整理编辑!