JavaRush /Java Blog /Random-ID /Rehat kopi #143. Kelas tersegel di Java 17. 4 cara mengim...

Rehat kopi #143. Kelas tersegel di Java 17. 4 cara mengimplementasikan Singleton

Dipublikasikan di grup Random-ID

Kelas tertutup di Java 17

Sumber: Codippa Dalam postingan ini kita akan melihat kelas tersegel, fitur baru yang diperkenalkan di Java 17, dan cara mendeklarasikan serta menggunakannya beserta contoh. Rehat kopi #143.  Kelas tersegel di Java 17. 4 cara mengimplementasikan Singleton - 1Kelas tersegel pertama kali muncul di Java 15 sebagai fitur pratinjau, dan kemudian di Java 16 dengan status yang sama. Fitur ini berfungsi penuh dengan dirilisnya Java 17 ( JEP 409 ).

Apa itu kelas tersegel?

Kelas tersegel memungkinkan Anda membatasi atau memilih subkelas. Suatu kelas tidak dapat memperluas kelas privat kecuali kelas tersebut ada dalam daftar kelas anak yang diizinkan di kelas induk. Kelas disegel menggunakan kata kunci yang disegel . Kelas yang disegel harus diikuti dengan kata kunci izin , beserta daftar kelas yang dapat memperluasnya. Berikut ini contohnya:
public sealed class Device permits Computer, Mobile {
}
Deklarasi ini berarti bahwa Perangkat hanya dapat diperluas oleh kelas Komputer dan Seluler . Jika ada kelas lain yang mencoba memperluasnya, kesalahan kompiler akan terjadi. Kelas yang memperluas kelas yang tersegel harus memiliki kata kunci final , tersegel , atau tidak tersegel dalam deklarasinya . Jadi kita memiliki hierarki kelas yang tetap. Apa hubungannya dengan pembuatan kelas anak?
  1. final berarti tidak dapat disubklasifikasikan lebih lanjut.

  2. disegel berarti kita perlu mendeklarasikan kelas anak yang memiliki izin .

  3. non-sealed berarti di sini kita mengakhiri hierarki induk-anak .

Misalnya, Komputer mengizinkan kelas Laptop dan Desktop selama Laptop itu sendiri tetap tidak tersegel . Artinya Laptop bisa diperluas ke kelas-kelas seperti Apple , Dell , HP dan sebagainya.

Tujuan utama memperkenalkan kelas tertutup adalah:

  1. Hingga saat ini, Anda hanya dapat membatasi ekstensi suatu kelas menggunakan kata kunci final . Kelas tersegel mengontrol kelas mana yang dapat memperluasnya dengan memasukkannya ke dalam daftar yang diizinkan.

  2. Hal ini juga memungkinkan kelas untuk mengontrol kelas mana yang akan menjadi kelas turunannya.

Aturan

Beberapa aturan yang perlu diingat saat menggunakan kelas tersegel:
  1. Kelas yang disegel harus mendefinisikan kelas yang dapat memperluasnya menggunakan izin . Hal ini tidak diperlukan jika kelas anak didefinisikan dalam kelas induk sebagai kelas dalam.

  2. Kelas anak harus final , disegel , atau tidak tersegel .

  3. Kelas anak yang diizinkan harus memperluas kelas tersegel induknya.

    Artinya, jika kelas A yang disegel mengizinkan kelas B, maka B harus memperluas A.

  4. Jika kelas yang disegel berada dalam sebuah modul, maka kelas turunannya juga harus berada dalam modul yang sama, atau dalam paket yang sama jika kelas induk yang disegel berada dalam modul yang tidak disebutkan namanya.

  5. Hanya kelas yang diizinkan secara langsung yang dapat memperluas kelas tersegel. Artinya, jika A adalah kelas tersegel yang mengizinkan B untuk memperluasnya, maka B juga merupakan kelas tersegel yang mengizinkan C.

    Maka C hanya dapat memperluas B, tetapi tidak dapat langsung memperluas A.

Antarmuka Tersegel

Seperti kelas yang disegel, antarmuka juga dapat disegel. Antarmuka seperti itu memungkinkan pemilihan antarmuka atau kelas turunannya, yang dapat memperluasnya menggunakan izin . Berikut ini contoh yang bagus:
public sealed interface Device permits Electronic, Physical,
DeviceImpl {
}
Di sini, antarmuka Perangkat memungkinkan antarmuka Elektronik dan Fisik untuk memperluasnya dan kelas DeviceImpl untuk implementasi selanjutnya.

Catatan Tersegel

Kelas tertutup dapat digunakan dengan entri yang diperkenalkan di Java 16. Entri tidak dapat memperluas kelas reguler, sehingga hanya dapat mengimplementasikan antarmuka pribadi. Selain itu, notasi tersebut menyiratkan final . Oleh karena itu, sebuah entri tidak dapat menggunakan kata kunci izin karena tidak dapat disubklasifikasikan. Artinya, hanya ada hierarki satu tingkat dengan catatan. Berikut ini contohnya:
public sealed interface Device permits Laptop {
}
public record Laptop(String brand) implement Device {
}

Dukungan refleksi

Java Reflection menyediakan dukungan untuk kelas yang disegel. Dua metode berikut telah ditambahkan ke java.lang.Class :

1.getPermissionSubclasses()

Ini mengembalikan array java.lang.Class yang berisi semua kelas yang diizinkan 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:
Ponsel Komputer

2. Tersegel()

Ini mengembalikan nilai true jika kelas atau antarmuka di mana ia dipanggil disegel. Itu saja untuk saat ini tentang kelas tersegel yang ditambahkan di Java 17. Saya harap artikel ini informatif.

4 Cara Menerapkan Singleton

Sumber: Medium Hari ini Anda akan mempelajari beberapa cara menerapkan pola desain Singleton. Pola desain Singleton banyak digunakan dalam proyek Java. Ini memberikan kontrol akses ke sumber daya, seperti soket atau koneksi database. Saya pernah diminta untuk mengimplementasikan singleton saat wawancara untuk posisi pengembang web di sebuah perusahaan chip besar. Ini adalah pertama kalinya saya melakukan wawancara untuk posisi web, dan saya tidak melakukan banyak persiapan, jadi saya memilih solusi yang paling sulit: Instansiasi yang malas. Kode saya hanya 90% benar dan kurang efisien, saya akhirnya kalah di babak final... Jadi semoga artikel saya bermanfaat bagi anda.

Instansiasi Awal

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

    public static Singleton getInstance() {
        return instance;
    }
}
Karena objek sudah dibuat saat inisialisasi, tidak ada masalah keamanan thread di sini, tetapi hal ini membuang-buang sumber daya memori jika tidak ada yang menggunakannya.

Implementasi yang malas

class Singleton {
    private static Singleton instance = null;
    private Singleton() {}
    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}
Saat menggunakan pola inisialisasi malas, objek dibuat sesuai permintaan. Namun, metode ini memiliki masalah keamanan thread: jika dua thread dimulai pada baris 5 secara bersamaan, keduanya akan membuat dua instance Singleton. Untuk menghindari hal ini, kita perlu menambahkan 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;
    }
}
Double-Checked Locking (DCL): Tidak ada penguncian pada jalur 6, sehingga jalur ini akan bekerja sangat cepat jika objek sudah dibuat. Mengapa kita perlu memeriksa ulang instance == null ? Karena mungkin ada dua utas yang diperkenalkan pada baris 7: yang pertama memulai objek, yang kedua menunggu Singleton.class lock . Jika tidak ada centang, maka thread kedua akan membuat ulang objek tunggal lagi. Namun cara ini tetap berbahaya bagi thread. Baris 9 dapat dibagi menjadi tiga baris kode byte:
  1. Alokasikan memori.
  2. Init objek.
  3. Tetapkan objek ke referensi instance.
Karena JVM dapat rusak, mesin virtual dapat menetapkan objek ke referensi instance sebelum inisialisasi. Utas lain sudah melihat != null instance , ia akan mulai menggunakannya dan menyebabkan masalah. Jadi kita perlu menambahkan volatil ke instance tersebut, maka kodenya 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 dalam statis

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 adalah kelas dalam statis, hanya diinisialisasi ketika metode getInstance dipanggil . Kelas init di JVM akan menjalankan <clinit> cmd , kemudian JVM sendiri akan memastikan bahwa hanya satu thread yang dapat memanggil <clinit> pada kelas target, thread lainnya akan menunggu.

Enum sebagai lajang

public enum EnumSingleton {
    INSTANCE;
    int value;
    public int getValue() {
        return value;
    }
    public int setValue(int v) {
        this.value = v;
    }
}
Secara default, instance enum aman untuk thread, jadi tidak perlu khawatir tentang penguncian yang dicentang ulang, dan cukup mudah untuk menulis.
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION