Java基础之String深入解析

Java基础之String深入解析


以下是本文目录大纲

  1. 生成地方和地址指向,intern()方法
  2. String可否被继承?

1. 生成地方和地址指向,intern()方法


先看代码

		String s1 = new String("abc");
        String s2 = "abc";
        String s3 = new String("abc");

        System.out.println(s1 == s2);
        System.out.println(s1 == s3);
        System.out.println(s2 == s3);

问题:

  1. s1,s2,s3分别在哪?生成了几个对象?
  2. 结果是什么?

先看程序运行的结果

false
false
false

解析:

  • String s1 = new String("abc");
    "abc" 会在字符串常量池里面生成一个字符串abc
    new String("abc"); 会在堆里面生成 abc的对象
  • String s2 = "abc";
    由于"abc"在字符串常量池里,所以可以直接引用
  • String s3 = new String("abc");
    “abc” 先在常量池里找,找到了就不在常量池里生成了,但是
    new String("abc");会在堆里面再生成一个对象abc

画图如下:
在这里插入图片描述

结论:
1. 生成3个abc对象,一个在字符串常量池里,两个在堆里
2. 结果如上


扩展加强

先看代码

 String s1 = new String("abc");
        String s2 = "abc";
        String s3 = new String("abc");

        System.out.println(s1 == s1.intern());
        System.out.println(s2 == s2.intern());
        System.out.println(s1.intern() ==s2.intern());

备注:当使用intern()方法时,查询字符串常量池是否存在当前字符串,若不存在则将当前字符串复制到字符串常量池中,并返回字符串常量池中的引用。


问题:

  1. 结果是分别是什么?

解析:

  • s1.intern()返回常量池里中abc对象,s1是堆对象abc,所以false
  • 同理,s2,s2.intern()都指向字符串常量池中的对象abc,所以true
  • s1.intern()s2.intern()都指向字符串常量池中的对象abc,所以true

画图如下:
在这里插入图片描述


结论:

false
true
true


2. String可否被继承?


先看代码

		String s4 = "java";
        String s5 = "ja";
        String s6 = "va";
        System.out.println(s4 == "java");
        System.out.println(s4 == (s5 + s6));
        System.out.println(s4 == "ja" + s6);
        System.out.println((s5+s6)== "ja" + s6);

解析:

  • s4 == "java",都是常量池里的对象,返回true
  • (s5+s6)会在堆里面生成 “java”,所以s4 == (s5 + s6)返回false
  • 同理"ja" + s6也会在堆里面生成 “java”,所以(s5+s6)== "ja" + s6返回false
  • (s5+s6) == "ja" + s6 等号两边引用的对象虽然相同,但是生成的对象是不一样的,所以返回false

画图如下:
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java中的String a = new String("a")创建了两个对象,一个是存储字符串"a"的String常量池中的对象,另一个则是通过new关键字在堆内存中新创建的String对象。 下面我们来深入探讨一下这个问题,需要了解以下几个概念: 1. String对象的不可变性 2. 字符串常量池 3. Java中的内存分配 1. String对象的不可变性 在Java中,String对象是不可变的,一旦被创建,它的值就不能被更改。这是因为Java中的String类是final的,不能被继承。 例如,当我们对String对象进行修改时,实际上是创建了一个新的String对象,而原来的String对象并没有被修改。 例如: ``` String str = "hello"; str = str + "world"; ``` 在这个例子中,"hello"和"world"都是String对象,但是当我们将它们拼接起来时,实际上是创建了一个新的String对象"helloworld",而原来的"hello"和"world"对象并没有被修改。 2. 字符串常量池 字符串常量池是Java中的一种特殊的内存区域,用于存储String常量。在Java中,如果我们使用双引号定义一个字符串,那么这个字符串就会被存储在字符串常量池中。例如: ``` String str1 = "hello"; String str2 = "hello"; ``` 在这个例子中,str1和str2都是指向字符串常量池中的"hello"对象,因此它们在内存中是同一个对象。 需要注意的是,字符串常量池中的对象是不可变的,一旦被创建,它的值就不能被更改。 3. Java中的内存分配 Java中的内存分为栈内存和堆内存两种。栈内存用于存储局部变量和方法调用栈,而堆内存用于存储对象。 当我们使用new关键字创建一个对象时,它会被分配到堆内存中。例如: ``` String str = new String("hello"); ``` 在这个例子中,"hello"字符串被存储在字符串常量池中,而通过new关键字创建的String对象则被分配到了堆内存中。 结合以上三个概念,我们可以对题目进行深入分析: ``` String a = new String("a"); ``` 根据第3点,new关键字会在堆内存中创建一个新的String对象,因此这里至少会创建一个对象。 根据第1点和第2点,我们知道字符串常量池中已经有了一个值为"a"的String对象,如果这个对象没有被其他变量引用,那么第一次执行上述代码时,会在堆内存中创建一个新的String对象,并将常量池中的"a"字符串复制到堆内存中的新对象中。因此,此时会创建两个对象,一个在字符串常量池中,一个在堆内存中。 但是,如果常量池中已经有了一个值为"a"的String对象,并且它被其他变量引用了,那么第一次执行上述代码时,会在堆内存中创建一个新的String对象,但是这个对象中的字符串值会直接指向常量池中的"a"字符串。因此,此时只会创建一个对象。 总之,在Java中,创建String对象的方式很多,而创建的对象数量也会受到多种因素的影响。对于一个简单的语句,可能需要深入分析才能得出准确的答案。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值