Kelas tidak berubah adalah bermanfaat kerana ia sememangnya selamat untuk benang, mudah untuk difikirkan dan menghalang perubahan yang tidak disengajakan pada keadaan objek. Keadaan objek tidak berubah tidak boleh diubah suai selepas ia dicipta, menjadikannya corak reka bentuk yang berharga, terutamanya dalam persekitaran berbilang benang.
Pertimbangkan kelas Pekerja berikut:
final class Employee { private final long id; private final String name; private final double salary; public Employee(long id, String name, double salary) { this.id = id; this.name = name; this.salary = salary; } public long getId() { return id; } public String getName() { return name; } public double getSalary() { return salary; } }
Dalam pendekatan tradisional ini:
Walaupun pendekatan ini berfungsi dengan baik, ia melibatkan penulisan kod boilerplate untuk pembina, getter, dan kadangkala sama, hashCode dan kaedah toString.
Lombok boleh mengurangkan jumlah kod yang perlu anda tulis secara drastik. Begini cara anda boleh mencapai fungsi yang sama dengan Lombok:
import lombok.AllArgsConstructor; import lombok.Getter; @AllArgsConstructor @Getter final class Employee { private final long id; private final String name; private final double salary; }
Versi ini menggunakan anotasi Lombok untuk menjana pembina dan pengambil secara automatik:
Anotasi @Value Lombok ialah alternatif yang lebih berkuasa yang menggabungkan berbilang ciri untuk mencipta kelas yang tidak berubah:
import lombok.Value; @Value class Employee { long id; String name; double salary; }
Dengan @Value, Lombok secara automatik:
Ini mengurangkan definisi kelas anda kepada hanya medan, dengan semua kod yang diperlukan dijana secara automatik.
Objek tidak berubah tidak membenarkan pengubahsuaian keadaannya. Walau bagaimanapun, dalam kes tertentu, anda mungkin perlu membuat salinan objek yang diubah suai, seperti mengemas kini gaji pekerja. Tanpa Lombok, ini mungkin kelihatan seperti:
@Value class Employee { long id; String name; double salary; } class Main { public static void main(String... args) { var emp = new Employee(1L, "Aman", 10_000.0); emp = updateSalary(emp, 12_0000.0); } public Employee updateSalary(Employee emp, long newSalary) { return new Employee(emp.getId(), emp.getName(), newSalary); } }
Ini mudah tetapi membosankan, terutamanya apabila berurusan dengan kelas yang mempunyai banyak bidang.
Lombok @Dengan anotasi memudahkan ini:
import lombok.Value; import lombok.With; @Value class Employee { long id; String name; @With double salary; } class Main { public static void main(String... args) { var emp = new Employee(1L, "Aman", 10_000.0); emp = updateSalary(emp, 12_0000.0); } public Employee updateSalary(Employee emp, double newSalary) { return emp.withSalary(newSalary); } }
Anotasi @With menjana kaedah yang mengembalikan tika baharu kelas dengan medan yang ditentukan dikemas kini, meninggalkan selebihnya tidak berubah.
Versi de-lombok kelas Pekerja kami (iaitu, apa yang Lombok jana di bawah hud) akan kelihatan seperti ini:
final class Employee { private final long id; private final String name; private final double salary; public Employee(long id, String name, double salary) { this.id = id; this.name = name; this.salary = salary; } public Employee withSalary(double salary) { return this.salary == salary ? this : new Employee(this.id, this.name, salary); } public long getId() { return this.id; } public String getName() { return this.name; } public double getSalary() { return this.salary; } @Override public boolean equals(final Object o) { if (o == this) return true; if (!(o instanceof Employee)) return false; final Employee other = (Employee) o; if (this.getId() != other.getId()) return false; final Object this$name = this.getName(); final Object other$name = other.getName(); if (this$name == null ? other$name != null : !this$name.equals(other$name)) return false; return Double.compare(this.getSalary(), other.getSalary()) == 0; } @Override public int hashCode() { final int PRIME = 59; int result = 1; final long $id = this.getId(); result = result * PRIME + (int) ($id >>> 32 ^ $id); final Object $name = this.getName(); result = result * PRIME + ($name == null ? 43 : $name.hashCode()); final long $salary = Double.doubleToLongBits(this.getSalary()); result = result * PRIME + (int) ($salary >>> 32 ^ $salary); return result; } @Override public String toString() { return "Employee(id=" + this.getId() + ", name=" + this.getName() + ", salary=" + this.getSalary() + ")"; } }
Walaupun Lombok memudahkan mencipta kelas yang tidak berubah, adalah penting untuk mengambil perhatian beberapa kemungkinan perangkap:
Walaupun kebolehubahan menawarkan faedah yang ketara, adalah penting untuk mempertimbangkan kesan prestasi, terutamanya dalam senario yang melibatkan kemas kini yang kerap:
Lombok's @Value dan @With anotasi menawarkan cara yang hebat dan ringkas untuk mencipta kelas tidak berubah di Jawa, menghapuskan keperluan untuk kod boilerplate dan menjadikan kod anda lebih mudah dibaca dan diselenggara. Dengan memanfaatkan anotasi ini, anda boleh menumpukan pada logik aplikasi anda dan bukannya mekanik reka bentuk kelas.
Atas ialah kandungan terperinci Ubah Kod Java Anda: Buka Kunci Kuasa Keabadian dengan Lombok dalam Hanya Minit!. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!