经典面试题:String str = new String("abc")会创建几个对象?

在JVM中,会单独划分一块内存给String。字符串的分配需要消耗高昂的时间和空间,且使用又比较频繁。JVM为了提高性能和减少内存的开销,在实例化字符串的时候进行优化:使用字符串常量池。每当创建字符串常量时,JVM会先检查字符串常量池,如果存在,则返回引用地址;如果不存在,就会实例化该字符串并且放到常量池中。由于String字符串的不可变性,常量池中不会出现两个相同的字符串。

如果在常量池中,“abc”如果存在,就直接把“abc”对象的引用地址赋给str。找不到则创建对象“abc”,再把地址赋给str。

Object obj = new Object();
平常都会说创建了obj对象,事实上obj只是一个变量,变量里保存了Object对象的引用地址。
引用类型声明的变量是指该变量在内存中实际存储的一个引用地址,实体在堆中。

所以说变量是可以变的,但是实体对象不能变,即str是可变的,但“abc”不可变。

那么,String为什么是不可变的?

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

    private final char value[];
    private int hash; // Default to 0
    public String() {
        this.value = new char[0];
    }

    public String(String original) {
        this.value = original.value;
        this.hash = original.hash;
    }
    ...
}

由源码可知:

  1. String类是final修饰的;
  2. String存储内容是char数组;
  3. char数组是final修饰的。

final关键字
1.修饰类:则类不可被继承,类中的成员变量可以按需求设为final,类中的方法隐式被指定为final;
2.修饰方法:不能重写(但可被重载几个final修饰的方法)。这里需注意:重写的前提是子类可继承父类此方法,若final修饰的方法同时也是private的,则子类中定义了同样的方法名和参数,则不产生重写与final的冲突,也就是说该方法属于子类,与父类没有关系。(类的private方法,隐式的被指定为final方法)
3.修饰基本数据类型:表示该基本数据类型的值一旦被初始化后就不能被改变。
4.修饰引用类型:初始化后不能再指向其他对象(引用地址不可变),但对象的内容可以发生改变。
5.修饰成员变量(属性):必须要显示初始化。(两种初始化方式:a.申明的时候赋值;b.在其类的所有构造器中都为其赋值。)。

String的其它方法
    public String concat(String str) {
        int otherLen = str.length();
        if (otherLen == 0) {
            return this;
        }
        int len = value.length;
        char buf[] = Arrays.copyOf(value, len + otherLen);
        str.getChars(buf, len);
        //返回新的对象
        return new String(buf, true);
    }
    public String replace(char oldChar, char newChar) {
        if (oldChar != newChar) {
            int len = value.length;
            int i = -1;
            char[] val = value; /* avoid getfield opcode */

            while (++i < len) {
                if (val[i] == oldChar) {
                    break;
                }
            }
            if (i < len) {
                char buf[] = new char[len];
                for (int j = 0; j < i; j++) {
                    buf[j] = val[j];
                }
                while (i < len) {
                    char c = val[i];
                    buf[i] = (c == oldChar) ? newChar : c;
                    i++;
                }
                return new String(buf, true);
            }
        }
        return this;
    }

String的方法都不是在原有的字符串上进行的,而是重新生成一个新的字符串对象。即原始字符串是不改变的。

结论:

  • String对象一旦被创建就是固定不变的,对于String的任何改变都不会影响到原对象,相关的任何变化性的操作都会生成新的对象。
  • String对象每次有变化性操作(有变化的情况)的时候,都会new一个String对象。
各JDK版本的常量位置.png

分析:

String str = new String("abc");
首先,new一个对象在堆中,将new String("abc")的对象的引用地址赋值给变量str。先去常量池查找“abc”是否存在。若存在,直接放引用地址;若不存在,创建“abc”对象,并将引用地址赋给String的有参构造里。

答案:

如果常量池中存在,则只需创建一个对象,否则需要创建两个对象。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,734评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,931评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,133评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,532评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,585评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,462评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,262评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,153评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,587评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,792评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,919评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,635评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,237评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,855评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,983评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,048评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,864评论 2 354

推荐阅读更多精彩内容