搜索
写经验 领红包
 > 地理

stig对象的特点(stig对象存在哪里)

导语:谈谈你对String对象的了解

string对象的特点(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类对象虽然结果一样,但是本质上有很多区别,通过直接赋值的方式为字符串赋值时,此时的字符串存储在方法区的字符串常量池中;通过构造器方式实例化字符串时,字符串对象存储在堆中,但是字符串的值仍然存储在方法区的常量池中。

本文内容由小茹整理编辑!