search

Home  >  Q&A  >  body text

Java: 不同String 相加在内存里的分布?

    String str1 = "a";
    String str2 = "b";
    String str3 = "ab";
    String str4 = new String("a");
    String str5 = new String("b");
    String str6= new String("ab");
    
    
    String plus1 = str1 + str2; 
    String plus2 = str1 + "b"; 
    String plus3 = str4 + "b";
    String plus4 = "a" + "b";
    String plus5 = str4 + str5;
    String plus6 = str4 + str2;

string相加有上面的6种情况
我想弄清楚各种情况的区别,我知道的是plus4都是在栈区,所以结果是一个字符串常量池里的常量,但是其他情况呢?
另外,我打印plus1~plus6的地址或者hashcode,发现都是一样的,怎么回事?

迷茫迷茫2802 days ago819

reply all(3)I'll reply

  • PHP中文网

    PHP中文网2017-04-18 10:32:17

    The answer on the first floor is too general, and talking about memory allocation regardless of JVM and JDK versions is just a rogue.

    Take the question as an example:

    String str1 = "a";
    String str2 = "b";
    String str3 = "ab";

    This kind of direct definition of a string, the JVM considers the string to be an invariant, that is, thread-safe, because this kind of string is directly allocated in the constant pool in the method area.

    String str4 = new String("a");
    String str5 = new String("b");
    String str6= new String("ab");

    There is the new keyword, indicating that this string is allocated on the heap. You can use the following method to verify:

    public static void main(String[] args) {
        String str1 = "a";
        String str2 = "b";
        String str3 = "ab";
        
        String str4 = new String("a");
        String str5 = new String("b");
        String str6= new String("ab");
        
        System.out.println(str1 == str4);   // false,说明str1和str4的内存地址不一样,一个在方法区,一个在堆.
        System.out.println(str1 == str4.intern());  // true,str4存入常量池后并没有重新创建一块内存,而是使用了已有的常量句柄.
        }

    Answer why the hashcodes of plus1~6 are the same. It is because you did not rewrite the hashcode method of String. The implementation of String’s default hashcode is:

    @Override public int hashCode() {
        int hash = hashCode;
        if (hash == 0) {
            if (count == 0) {
                return 0;
            }
            for (int i = 0; i < count; ++i) {
                hash = 31 * hash + charAt(i);
            }
            hashCode = hash;
        }
        return hash;
    }

    Only the literal constants are processed, and the literal constants of plus1~6 are the same, so the hashcode values ​​are of course the same. Then the hashcode is consistent, which does not mean that the memory addresses allocated by them in the jvm are consistent.

    reply
    0
  • ringa_lee

    ringa_lee2017-04-18 10:32:17

    There is only one instance of the same string in memory

    --------------------------------Separating line----------------

    This answer is too general and misleading. Please refer to Brother Zhengyi’s answer

    reply
    0
  • 大家讲道理

    大家讲道理2017-04-18 10:32:17

    The person above is right, the same string literal will only have one value in the method area. This is the commonly mentioned usage difference between string and stringbuffer.

    I will add below:
    String str4 = new String("a");
    The "a" literal is stored in the method area of ​​​​the jvm.
    str4 This object is stored in the heap.
    The above sentence means that 2 memory addresses are allocated.
    The stack stores 8 basic types and returnAddress and reference. Strings are not stored in the stack.
    As for the usage of hashcode, it is used for matching and positioning. You can go to Baidu yourself to find out the difference between hashcode and == and equals.
    Also, the memory addresses of plus1-6 are definitely different. I don't know how you found it to be the same. . .

    If there is anything I don’t understand correctly, please give me some advice.

    reply
    0
  • Cancelreply