JavaRush /Blog Java /Random-MS /Coffee break #143. Kelas tertutup dalam Java 17. 4 cara u...

Coffee break #143. Kelas tertutup dalam Java 17. 4 cara untuk melaksanakan Singleton

Diterbitkan dalam kumpulan

Kelas tertutup di Java 17

Sumber: Codippa Dalam siaran ini kita akan melihat kelas tertutup, ciri baharu yang diperkenalkan dalam Java 17, dan cara mengisytiharkan serta menggunakannya dengan contoh. Coffee break #143.  Kelas tertutup dalam Java 17. 4 cara untuk melaksanakan Singleton - 1Kelas tertutup pertama kali muncul di Java 15 sebagai ciri pratonton, dan kemudian di Java 16 dengan status yang sama. Ciri ini menjadi berfungsi sepenuhnya dengan keluaran Java 17 ( JEP 409 ).

Apakah kelas tertutup?

Kelas tertutup membolehkan anda menyekat atau memilih subkelas. Kelas tidak boleh melanjutkan kelas persendirian melainkan ia berada dalam senarai kelas induk kelas anak yang dibenarkan. Kelas dimeterai menggunakan kata kunci yang dimeterai . Kelas yang dimeterai mesti diikuti dengan kata kunci permit , bersama-sama dengan senarai kelas yang boleh melanjutkannya. Berikut ialah contoh:
public sealed class Device permits Computer, Mobile {
}
Pengisytiharan ini bermakna Peranti hanya boleh dilanjutkan oleh kelas Komputer dan Mudah Alih . Jika mana-mana kelas lain cuba memanjangkannya, ralat pengkompil akan dilemparkan. Kelas yang memanjangkan kelas yang dimeterai mesti mempunyai kata kunci muktamad , dimeterai atau tidak dimeterai dalam pengisytiharannya . Oleh itu kita mempunyai hierarki kelas tetap. Bagaimanakah ini berkaitan dengan mencipta kelas kanak-kanak?
  1. muktamad bermakna ia tidak boleh disubkelaskan lagi.

  2. dimeterai bermakna kita perlu mengisytiharkan kelas kanak-kanak dengan permit .

  3. tidak dimeterai bermakna di sini kita menamatkan hierarki ibu bapa-anak .

Sebagai contoh, Komputer membenarkan kelas Laptop dan Desktop selagi Laptop itu sendiri kekal tidak dimeterai . Ini bermakna Laptop boleh dilanjutkan mengikut kelas seperti Apple , Dell , HP dan sebagainya.

Matlamat utama memperkenalkan kelas tertutup ialah:

  1. Sehingga kini, anda hanya boleh mengehadkan pelanjutan kelas menggunakan kata kunci akhir . Kelas tertutup mengawal kelas mana yang boleh melanjutkannya dengan memasukkannya dalam senarai yang dibenarkan.

  2. Ia juga membenarkan kelas mengawal yang mana antara mereka akan menjadi kelas anak.

Peraturan

Beberapa peraturan yang perlu diingat apabila menggunakan kelas tertutup:
  1. Kelas tertutup mesti menentukan kelas yang boleh melanjutkannya menggunakan permit . Ini tidak diperlukan jika kelas anak ditakrifkan dalam kelas induk sebagai kelas dalaman.

  2. Kelas kanak-kanak mestilah sama ada muktamad , dimeterai atau tidak dimeterai .

  3. Kelas anak yang dibenarkan mesti melanjutkan kelas tertutup induknya.

    Iaitu, jika kelas A yang dimeterai membenarkan kelas B, maka B mesti melanjutkan A.

  4. Jika kelas yang dimeterai berada dalam modul, maka kelas anak juga mesti berada dalam modul yang sama, atau dalam pakej yang sama jika kelas yang dimeterai induk berada dalam modul yang tidak dinamakan.

  5. Hanya kelas yang dibenarkan secara langsung boleh melanjutkan kelas tertutup. Iaitu, jika A ialah kelas tertutup yang membolehkan B memanjangkannya, maka B juga kelas tertutup yang membolehkan C.

    Kemudian C hanya boleh memanjangkan B, tetapi tidak boleh memanjangkan A secara langsung.

Antara Muka Tertutup

Seperti kelas tertutup, antara muka juga boleh dimeterai. Antara muka sedemikian mungkin membenarkan pemilihan antara muka atau kelas anaknya, yang boleh memanjangkannya menggunakan permit . Berikut ialah contoh yang baik:
public sealed interface Device permits Electronic, Physical,
DeviceImpl {
}
Di sini, antara muka Peranti membenarkan antara muka Elektronik dan Fizikal untuk melanjutkannya dan kelas DeviceImpl untuk pelaksanaan seterusnya.

Rekod Termeterai

Kelas tertutup boleh digunakan dengan entri yang diperkenalkan dalam Java 16. Entri tidak boleh melanjutkan kelas biasa, jadi ia hanya boleh melaksanakan antara muka peribadi. Di samping itu, notasi membayangkan muktamad . Oleh itu, entri tidak boleh menggunakan kata kunci permit kerana ia tidak boleh disubkelaskan. Iaitu, hanya terdapat hierarki peringkat tunggal dengan rekod. Berikut ialah contoh:
public sealed interface Device permits Laptop {
}
public record Laptop(String brand) implement Device {
}

Sokongan refleksi

Java Reflection menyediakan sokongan untuk kelas tertutup. Dua kaedah berikut telah ditambahkan pada java.lang.Class :

1. getPermittedSubclasses()

Ini mengembalikan tatasusunan java.lang.Class yang mengandungi semua kelas yang dibenarkan oleh objek kelas ini. Contoh:
Device c = new Device();
Class<? extends Device> cz = c.getClass();
Class<?>[] permittedSubclasses = cz.getPermittedSubclasses();
for (Class<?> sc : permittedSubclasses){
  System.out.println(sc.getName());
}
Kesimpulan:
Mudah Alih Komputer

2.isSealed()

Ini kembali benar jika kelas atau antara muka di mana ia dipanggil dimeterai. Itu sahaja buat masa ini tentang kelas tertutup yang ditambahkan dalam Java 17. Saya harap artikel ini bermaklumat.

4 Cara Melaksanakan Singleton

Sumber: Sederhana Hari ini anda akan mempelajari beberapa cara untuk melaksanakan corak reka bentuk Singleton. Corak reka bentuk singleton digunakan secara meluas dalam projek Java. Ia menyediakan kawalan akses kepada sumber, seperti soket atau sambungan pangkalan data. Saya pernah diminta untuk melaksanakan singleton semasa temu duga untuk jawatan pembangun web di sebuah syarikat cip besar. Ini adalah kali pertama saya menemu duga untuk kedudukan web, dan saya tidak melakukan banyak persediaan, jadi saya memilih penyelesaian yang paling sukar: Instalasi malas. Kod saya hanya 90% betul dan tidak cukup cekap, saya akhirnya tewas di pusingan akhir... Jadi saya harap artikel saya akan berguna kepada anda.

Instalasi Awal

class Singleton {
    private Singleton() {}
    private static Singleton instance = new Singleton();

    public static Singleton getInstance() {
        return instance;
    }
}
Memandangkan objek telah dibuat semasa pemulaan, tiada isu keselamatan benang di sini, tetapi ia membazirkan sumber memori jika tiada sesiapa yang menggunakannya.

Perlaksanaan yang malas

class Singleton {
    private static Singleton instance = null;
    private Singleton() {}
    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}
Apabila menggunakan corak permulaan malas, objek dibuat atas permintaan. Walau bagaimanapun, kaedah ini mempunyai masalah keselamatan benang: jika dua utas dimulakan pada baris 5 pada masa yang sama, mereka akan mencipta dua kejadian Singleton. Untuk mengelakkan ini, kita perlu menambah kunci:
class Singleton {
    private Singleton() {}
    private static Singleton instance = null;

    public static Singleton getInstance() {
        if (instance == null) {
            synchronized(Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}
Penguncian Disemak Dua Kali (DCL): Tiada penguncian pada baris 6, jadi baris ini akan berfungsi dengan cepat jika objek telah dibuat. Mengapa kita perlu menyemak semula instance == null ? Kerana mungkin terdapat dua utas yang diperkenalkan pada baris 7: yang pertama memulakan objek, yang kedua sedang menunggu kunci Singleton.class . Jika tiada semakan, maka benang kedua akan mencipta semula objek tunggal. Walau bagaimanapun, kaedah ini masih berbahaya untuk benang. Baris 9 boleh dibahagikan kepada tiga baris kod bait:
  1. Peruntukkan ingatan.
  2. Init objek.
  3. Berikan objek kepada rujukan contoh.
Oleh kerana JVM boleh kehabisan susunan, mesin maya boleh menetapkan objek kepada rujukan contoh sebelum pemulaan. Benang lain sudah melihat contoh != null , ia akan mula menggunakannya dan menyebabkan masalah. Jadi kita perlu menambah tidak menentu pada contoh, maka kodnya menjadi seperti ini:
class Singleton {
    private Singleton() {}
    private volatile static Singleton instance = null;

    public static Singleton getInstance() {
        if (instance == null) {
            synchronized(Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

Menggunakan kelas dalaman statik

public class Singleton {
  private Singleton() {}
  private static class SingletonHolder {
    private static final Singleton INSTANCE = new Singleton();
  }
  public static final Singleton getInstance() {
    return SingletonHolder.INSTANCE;
  }
}
SingletonHolder ialah kelas dalaman statik, ia hanya dimulakan apabila kaedah getInstance dipanggil . Kelas init dalam JVM akan menjalankan <clinit> cmd , kemudian JVM itu sendiri akan memastikan bahawa hanya satu utas boleh memanggil <clinit> pada kelas sasaran, utas lain akan menunggu.

Enum sebagai singleton

public enum EnumSingleton {
    INSTANCE;
    int value;
    public int getValue() {
        return value;
    }
    public int setValue(int v) {
        this.value = v;
    }
}
Secara lalai, contoh enum adalah selamat untuk benang, jadi tidak perlu risau tentang penguncian yang disemak dua kali, dan ia agak mudah untuk ditulis.
Komen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION