Rumah  >  Artikel  >  Java  >  Analisis kod sumber tinju automatik dan nyahboxing Java

Analisis kod sumber tinju automatik dan nyahboxing Java

WBOY
WBOYke hadapan
2023-05-09 12:10:111265semak imbas

    Apakah pembungkusan & nyahkotak?

    Proses menukar jenis asas int kepada jenis pembungkusan Integer dipanggil boxing, dan sebaliknya dipanggil unboxing.

    Pertama lihat sekeping kod

    public static void main(String[] args) {
        Integer a = 127, b = 127;
        Integer c = 128, d= 128;
        System.out.println(a == b); // true
        System.out.println(c == d); // false
    }

    Saya tertanya-tanya jika orang lain tidak tahu mengapa benar dan salah muncul dalam kod ini. Ini membawa kita kepada operasi tinju Java. Kami menganalisis dengan soalan.

    Tinju (valueOf())

    public static Integer valueOf(int i) {
        // -128 - 127
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

    Kita boleh mendapati bahawa terdapat penghakiman pada permulaan Jika julat nilai adalah antara [-128,127], maka dari cache ini ( Tatasusunan Integer) , jika ia tidak berada dalam julat ini, buat yang baharu sahaja.

    Mengapa kita memerlukan cache [-128,127]?

    Saya faham apa yang saya maksudkan, kerana dalam perniagaan kami, mungkin terdapat medan jenis Integer seperti pelbagai status dan pengecam Nilai ini biasanya 0, 1, 2, 3 dan seumpamanya. dan ia kelihatan agak kerap Jika tiada cache, maka objek baru yang kerap diperlukan dan kemudian dikeluarkan, yang menggunakan banyak ruang memori Oleh itu, cache muncul, yang boleh membantu kami mengoptimumkan beberapa pembaziran ruang.

    Kenapa [-128,127]?

    Saya melihat perkara ini, saya tidak akan menerangkan sebab khusus di sini. Ia bergantung terutamanya pada pengetahuan asas komputer Selepas anda memahami kod asal, kod songsang dan kod pelengkap. Adalah mudah untuk mengetahui mengapa ia berada dalam julat ini.

    Nilai ini juga boleh ditukar melalui parameter permulaan.

    -XX:AutoBoxCacheMax=(saiz)

    Isu prestasi yang disebabkan oleh tinju automatik

    Sekarang anda harus faham mengapa kod di atas mempunyai hasil yang berbeza. Jadi, pernahkah anda terfikir , sebagai contoh, dalam gelung untuk perniagaan kami, data statistik yang serupa dengan operasi ini berlaku Jika terdapat tinju automatik, apakah masalah yang akan berlaku? Mari lihat sekeping kod berikut.

    public static void main(String[] args) {
        long startTime = System.currentTimeMillis();
        Integer count = 0;
        // int count = 0;
        for (int i = 0; i < 5000000; i++) {
            count += i;
        }
        System.out.println("计算时长:" + (System.currentTimeMillis() - startTime) + " ms");
    }
    
    // 执行结果:
    // Integer 计算时长:51 ms
    // int 计算时长:6 ms

    Kemudian melalui keputusan pelaksanaan, dapat diketahui dengan jelas bahawa objek baharu yang kerap dikotak-kotak secara automatik dan memori diperuntukkan, menyebabkan kehilangan prestasi dalam masa dan ruang.

    Ringkasan kecil

    Melalui pembacaan kod sumber dan analisis ujian, kita boleh membuat kesimpulan bahawa kita harus cuba mengelakkan jenis ini apabila kita biasanya mengira statistik atau memasukkan parameter ke dalam masalah penukaran . Untuk meningkatkan kecekapan pelaksanaan keseluruhan kod kami.

    Nyah kotak (intValue)

    Tiada logik rumit dalam menyahkotak dan ia secara langsung mengembalikan jenis asas nilai.

    Tambahan: Adakah tinju automatik dan nyahboxing sentiasa berlaku?

    Tidak semestinya. Lihat kod sampel di bawah Keputusan output telah diulas selepas pernyataan output.

    public static void main(String[] args) {
    // TODO 自动生成的方法存根
    Integer a = 1;
    Integer b = 2;
    Integer c = 3;
    Integer d = 3;
    Integer e = 321;
    Integer f = 321;
    Long g = 3L;
    System.out.println(c==d);//true
    //包装类的==在没有遇到算术运算的情况下不会自动拆箱
    System.out.println(e==f);//false
    System.out.println(c==(a+b));//true
    System.out.println(c.equals(a+b));//true
    System.out.println(g==(a+b));//true
    //equals方法不会处理数据转型关系
    System.out.println(g.equals(a+b));//false
    }

    Situasi di mana tinju automatik dan nyahboxing berlaku adalah seperti berikut:

    Autoboxing: Jenis asas diberikan kepada jenis pembungkusan. Contohnya: Integer i1 = 1;

    Nyahkotak automatik:

    1. Jenis pembungkusan ditetapkan kepada jenis asas. Contohnya: int i2 = new Integer(1);

    2. Bandingkan jenis int dengan jenis Integer. Jika nilai jenis int dan jenis Integer adalah sama, hasilnya sentiasa benar.

    3. Jenis integer menemui operasi aritmetik

    Tetapi mengapa dalam contoh di atas, System.out.println(c==d); .out.println(e==f);Hasil keluaran adalah berbeza?

    Terutamanya kerana kaedah Integer.valueOf(). Sebahagian daripada kod sumber Integer disiarkan di bawah:

      //
       private static class IntegerCache {
            static final int low = -128;
            static final int high;
            static final Integer cache[];
    
            static {
                // high value may be configured by property
                int h = 127;
                String integerCacheHighPropValue =
                    sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
                if (integerCacheHighPropValue != null) {
                    try {
                        int i = parseInt(integerCacheHighPropValue);
                        i = Math.max(i, 127);
                        // Maximum array size is Integer.MAX_VALUE
                        h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
                    } catch( NumberFormatException nfe) {
                        // If the property cannot be parsed into an int, ignore it.
                    }
                }
                high = h;
    
                cache = new Integer[(high - low) + 1];
                int j = low;
                for(int k = 0; k < cache.length; k++)
                    cache[k] = new Integer(j++);
    
                // range [-128, 127] must be interned (JLS7 5.1.7)
                assert IntegerCache.high >= 127;
            }
                private IntegerCache() {}
        }
        
      public static Integer valueOf(int i) {
            if (i >= IntegerCache.low && i <= IntegerCache.high)
                return IntegerCache.cache[i + (-IntegerCache.low)];
            return new Integer(i);
        }

    IntegerCache ialah kelas dalaman statik Integer, dan valueOf() ialah kaedah pembungkusan. Seperti yang dapat dilihat daripada kod sumber, cache ialah tatasusunan cache Apabila parameter input i kaedah valueOf() berada dalam julat [-128,127], nilai Integer dalam tatasusunan cache akan dikembalikan Integer akan dibuat.

    Inilah sebab mengapa hasil keluaran System.out.println(c==d); dan System.out.println(e==f); c dan d berada dalam selang cache, jadi mereka mengembalikan rujukan yang sama manakala e dan f tidak berada dalam selang cache, mereka mengembalikan Integer baharu, yang bukan lagi rujukan yang sama.

    Atas ialah kandungan terperinci Analisis kod sumber tinju automatik dan nyahboxing Java. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

    Kenyataan:
    Artikel ini dikembalikan pada:yisu.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam