Java String 解析

Java String 解析

1. String为什么是不可变对象

首先String不属于8种基本数据类型,String是一个对象。

内部成员变量

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];

    /** Cache the hash code for the string */
    private int hash; // Default to 0
    }

可以看出String的内部是采用char数组实现的,而且value被声明为final类型,标明其在初始化后value值不能被改变,由此可以看出String是不可变得。

但是其并不是完全不可变得,通过反射技术可以改变String的值 如下:

  String count = new String("1");

        Class stringClass = Class.forName("java.lang.String");

        Field field =stringClass.getDeclaredField("value");
        //设置私有成员可见性
        field.setAccessible(true);
        //获取原值
        char[] test = (char[])field.get(count);

        //修改
        test[0]='2';

        //count被修改成2
        System.out.println(count.toString());

2. String str = “test” 与String str = new String(“test”)的区别;

String str = “test”字面量创建形成:

当代码中出现字面量形式创建字符串对象时,JVM首先会对这个字面量进行检查,如果字符串常量池中存在相同内容的字符串对象的引用,则将这个引用返回,否则新的字符串对象被创建,然后将这个引用放入字符串常量池,并返回该引用。

String str = new String(“test”)正常创建

会在堆上分配内存,栈上分配引用

  • 堆:存放所有new出来的对象
  • 栈:存放基本类型的变量数据和对象的应用,对象(new出来的对象)本身并不存在栈中,而是存放在堆中或者常量池中(字符串常量对象存放在常量池中)
  • 常量池:存放基本类型常量和字符串常量。

对于栈和常量池中的对象可以共享,对于堆中的对象不可以共享。栈中的数据大小和生命周期是可以确定的,当没有引用指向数据时,这个数据就会自动消失。堆中的对象的由垃圾回收器负责回收,因此大小和生命周期不需要确定,具有很大的灵活性。

你可能感兴趣的:(Java基础)