黑马程序员--05.String字符串类--01. String s1=new String (a)内存图【个人总结】

来源:互联网 发布:socket用法 java 编辑:程序博客网 时间:2024/06/04 17:51

String s1=new String(“a”)内存图

----------- android培训、java培训、java学习型技术博客、期待与您交流! ------------

1.    问题描述

【1】Strings1=new String ("a");

说法:new 了一个对象,"a"也是一个对象;"a"不是相当于一个参数么?为什么说"a"是个对象?

【2】内存图的样子是什么?

【3】分析

{1}. 由于当时看到这个问题之后,自己也不是很清楚,所以,不得不借助一下String类的参数是String的重载的构造方法

/**

* Initializesa newly created {@code String} object so that it represents

 *the same sequence of characters as the argument; in other words, the

 *newly created string is a copy of the argument string. Unless an

 *explicit copy of {@code original} is needed, use of this constructor is

 *unnecessary since Strings are immutable.

 *

 * @param original

 *        A {@code String}

 */

public String(String original) {…}

{2}. 现在分析一下这个方法什么时候使用:

我翻译一下上面这段对这个构造方法的说明:

*************************************************************************

这个构造方法用来初始化一个和输入参数具有相同字符序列的字符串对象。换句话说,新建的这个字符串对象是传入的字符串参数对象的一份副本。除非是明确地需要使用字符串复制功能,否则由于字符串常量值是不可变的,这个构造函数是没有必要去直接使用。(意译)

*************************************************************************

【结论】:以String为参数的构造函数开发中使用可能性已经很小。所以,这个构造方法主要在考题里面出现。


2.    源码分析

(1). 分析String类的成员属性 -----源码

public final class String

    implements java.io.Serializable,Comparable<String>, CharSequence{

    /** The value is used forcharacter storage. */

private final char value[]; //存储字符串中元素的字符数组

/*

注意:value引用常量:一旦初始化指向了一个内存中的数组

不能再指向别的数组了

*/

 

    /** The offset is the first indexof the storage that is used. */

    private final int offset;    //value存储字符串第一个索引位置---常量

 

    /** The count is the number ofcharacters in the String. */

    private final int count; //value存储字符串长度---常量

...

}

【结论】这样Java实际上是使用指针(offset)计数器(count)字符数组(value[])来描述String类的

大概就是下图:一旦通过构造函数初始化这个新建的字符串之后,这个字符数组对应的指针计数器都是固定的,不能改变了

(2). 分析String类的publicString(String original) -----源码

public String(String original) {

        //size表示参数数组真实长度----赋值给新的变量的原因就是countfinal

int size = original.count;

//originalValue表示参数数组字符数组----赋值给新的变量的原因就value[]

//final

        char[] originalValue = original.value;

        char[] v;//临时定义的字符数组

       

//参数的字符数组中没有存满有效字符

if (originalValue.length > size) {

            int off = original.offset;//----赋值给新的变量:offset也是final

            /*

                注意Arrays的这个静态方法的返回值:

a new array containing thespecified range from the original

array, truncated or padded withnull characters to obtain the

required length

                意思是:返回包含原数组指定范围的一个新的数组。

为了能获取(off, off + size)这个长度:

如果原数组数组不够这么长,用null字符串来填充以达到指定长度

*/

v =Arrays.copyOfRange(originalValue, off, off + size);

//v指向了新的数组

        }else {//参数的字符数组中正好存满有效字符

            v= originalValue;

        }

        this.offset = 0;

        this.count = size;

        this.value = v;

    }

3.    内存图演示

(1). 回答问题1:“a”是存储在常量池的字符串

(2). 回答问题2:

String s1=newString ("abc"); 通过上面的构造方法初始化之后,常量池中的" abc"和这个新在堆内存中的对象s1已经没有关系了。

(3). 内存图演示


----------- android培训、java培训、java学习型技术博客、期待与您交流! ------------

 

原创粉丝点击