Java: 不同String 相加在内存里的分布?
迷茫
迷茫 2017-04-18 10:30:17
0
3
751
    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,发现都是一样的,怎么回事?

迷茫
迷茫

业精于勤,荒于嬉;行成于思,毁于随。

membalas semua(3)
Ty80

Jawapan di tingkat satu terlalu umum, dan bercakap tentang peruntukan memori tanpa mengira versi JVM dan JDK hanyalah penyangak.

Ambil soalan sebagai contoh:

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

Definisi langsung rentetan jenis ini, JVM menganggap rentetan itu sebagai invarian, iaitu selamat untuk benang, kerana rentetan jenis ini diperuntukkan secara langsung dalam kolam malar dalam kawasan kaedah.

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

mempunyai kata kunci baharu, yang menunjukkan bahawa rentetan ini diperuntukkan pada timbunan Anda boleh menggunakan kaedah berikut untuk mengesahkan:

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存入常量池后并没有重新创建一块内存,而是使用了已有的常量句柄.
    }

Jawab mengapa kod cincang tambah1~6 adalah sama kerana anda tidak mengatasi kaedah kod cincang String. Pelaksanaan kod cincang lalai String ialah:

@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;
}

Hanya pemalar literal diproses dan pemalar literal tambah1~6 adalah sama, jadi nilai kod cincang sudah tentu sama. Kemudian kod cincang adalah konsisten, yang tidak bermakna alamat memori yang diperuntukkan oleh mereka dalam jvm adalah konsisten.

左手右手慢动作

Hanya terdapat satu contoh rentetan yang sama dalam ingatan

---------------------------------Barisan pemisah------------ --- -

Jawapan ini terlalu umum dan mengelirukan Sila rujuk jawapan Abang Yi

大家讲道理

Apa yang anda katakan di atas betul, literal rentetan yang sama hanya akan mempunyai satu nilai dalam kawasan kaedah. Ini ialah perbezaan yang biasa disebut dalam penggunaan antara string dan stringbuffer.

Saya akan menambah di bawah:
String str4 = new String("a");
Literatif "a" disimpan dalam kawasan kaedah jvm.
Objek str4 disimpan dalam timbunan.
Ayat di atas bermaksud 2 alamat memori diperuntukkan.
Timbunan menyimpan 8 jenis asas dan returnAddress dan rujukan tidak akan disimpan dalam tindanan.
Bagi penggunaan kod cincang, ia digunakan untuk pemadanan dan kedudukan. Anda boleh pergi ke Baidu sendiri untuk mengetahui perbezaan antara kod cincang dan == dan sama.
Lebih-lebih lagi, alamat memori plus1-6 pastinya berbeza. Saya tidak tahu bagaimana anda mendapati ia adalah sama. . .

Jika ada apa-apa yang saya tidak faham dengan betul, sila berikan saya nasihat.

Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!