Misalkan Anda perlu mendefinisikan kelas yang semuanya hanya memegang konstanta.
public static final String SOME_CONST = "SOME_VALUE";
Apa cara yang disukai untuk melakukan ini?
- Antarmuka
- Kelas Abstrak
- Kelas Akhir
Mana yang harus saya gunakan dan mengapa?
Klarifikasi untuk beberapa jawaban:
Enum - Saya tidak akan menggunakan enum, saya tidak menghitung apa pun, hanya mengumpulkan beberapa konstanta yang tidak terkait satu sama lain dengan cara apa pun.
Antarmuka - Saya tidak akan menetapkan kelas apa pun sebagai salah satu yang mengimplementasikan antarmuka. Hanya ingin menggunakan antarmuka untuk memanggil konstanta seperti: ISomeInterface.SOME_CONST
.
java
class-constants
Yuval Adam
sumber
sumber
Jawaban:
Gunakan kelas terakhir. untuk kesederhanaan Anda kemudian dapat menggunakan impor statis untuk menggunakan kembali nilai-nilai Anda di kelas lain
public final class MyValues { public static final String VALUE1 = "foo"; public static final String VALUE2 = "bar"; }
di kelas lain:
import static MyValues.* //... if(variable.equals(VALUE1)){ //... }
sumber
VALUE1.equals(variable)
karena menghindari NPE.Klarifikasi Anda menyatakan: "Saya tidak akan menggunakan enum, saya tidak menghitung apa pun, hanya mengumpulkan beberapa konstanta yang tidak terkait satu sama lain dengan cara apa pun."
Jika konstanta sama sekali tidak terkait satu sama lain, mengapa Anda ingin mengumpulkannya? Letakkan setiap konstanta di kelas yang paling terkait dengannya.
sumber
Saran saya (dalam urutan preferensi yang menurun):
1) Jangan lakukan itu . Buat konstanta di kelas sebenarnya yang paling relevan. Memiliki kelas / antarmuka 'bag of constants' tidak benar-benar mengikuti praktik terbaik OO.
Saya, dan semua orang, mengabaikan # 1 dari waktu ke waktu. Jika Anda akan melakukannya, maka:
2) kelas akhir dengan konstruktor privat Ini setidaknya akan mencegah siapa pun menyalahgunakan 'bag of constants' Anda dengan memperluas / menerapkannya untuk mendapatkan akses mudah ke konstanta. (Saya tahu Anda mengatakan Anda tidak akan melakukan ini - tetapi itu tidak berarti seseorang datang setelah Anda tidak mau)
3) antarmuka Ini akan berfungsi, tetapi bukan preferensi saya memberikan kemungkinan penyalahgunaan yang disebutkan di # 2.
Secara umum, hanya karena ini adalah konstanta bukan berarti Anda tidak harus tetap menerapkan prinsip oo normal padanya. Jika tidak ada kecuali satu kelas yang peduli tentang konstanta - itu harus privat dan di kelas itu. Jika hanya pengujian yang peduli tentang konstanta - pengujian harus berada dalam kelas pengujian, bukan kode produksi. Jika konstanta didefinisikan di banyak tempat (tidak hanya secara tidak sengaja sama) - refactor untuk menghilangkan duplikasi. Dan seterusnya - perlakukan mereka seperti Anda memperlakukan sebuah metode.
sumber
Seperti yang dicatat Joshua Bloch dalam Effective Java:
Anda dapat menggunakan Enum jika semua konstanta Anda terkait (seperti nama planet), meletakkan nilai konstanta di kelas yang terkait dengannya (jika Anda memiliki akses ke sana), atau menggunakan kelas utilitas yang tidak instan (tentukan konstruktor default pribadi) .
class SomeConstants { // Prevents instanciation of myself and my subclasses private SomeConstants() {} public final static String TOTO = "toto"; public final static Integer TEN = 10; //... }
Kemudian, seperti yang telah dinyatakan, Anda dapat menggunakan impor statis untuk menggunakan konstanta Anda.
sumber
Metode pilihan saya adalah tidak melakukan itu sama sekali. Umur konstanta cukup banyak mati ketika Java 5 memperkenalkan enum typesafe. Dan bahkan sebelum itu Josh Bloch menerbitkan versi (yang sedikit lebih bertele-tele) dari itu, yang bekerja pada Java 1.4 (dan sebelumnya).
Kecuali Anda memerlukan interoperabilitas dengan beberapa kode lama, sebenarnya tidak ada alasan untuk menggunakan konstanta String / integer lagi.
sumber
Gunakan saja kelas terakhir.
Jika Anda ingin dapat menambahkan nilai lain gunakan kelas abstrak.
Tidak masuk akal menggunakan antarmuka, antarmuka seharusnya menentukan kontrak. Anda hanya ingin mendeklarasikan beberapa nilai konstan.
sumber
Bukankah enum adalah pilihan terbaik untuk hal-hal semacam ini?
sumber
enum
s baik-baik saja. IIRC, satu item di Java efektif (2nd Ed) memilikienum
konstanta yang menghitung opsi standar yang mengimplementasikan [kata kunci Java]interface
untuk nilai apa pun.Preferensi saya adalah dengan menggunakan [Java kata kunci]
interface
di atasfinal class
untuk konstanta. Anda secara implisit mendapatkan filepublic static final
. Beberapa orang akan berpendapat bahwainterface
memungkinkan pemrogram yang buruk untuk menerapkannya, tetapi pemrogram yang buruk akan menulis kode yang menyebalkan apa pun yang Anda lakukan.Mana yang terlihat lebih baik?
public final class SomeStuff { private SomeStuff() { throw new Error(); } public static final String SOME_CONST = "Some value or another, I don't know."; }
Atau:
public interface SomeStuff { String SOME_CONST = "Some value or another, I don't know."; }
sumber
Atau 4. Letakkan mereka di kelas yang berisi logika yang paling banyak menggunakan konstanta
... maaf, tidak bisa menahan ;-)
sumber
Salah satu kelemahan dari private constructor adalah adanya metode yang tidak dapat diuji.
Konsep enum menurut sifatnya baik untuk diterapkan dalam tipe domain tertentu, menerapkannya pada konstanta desentralisasi terlihat tidak cukup baik
Konsep Enum adalah "Pencacahan adalah sekumpulan item yang terkait erat".
Memperluas / mengimplementasikan antarmuka konstan adalah praktik yang buruk, sulit untuk memikirkan persyaratan untuk memperluas konstanta yang tidak dapat diubah alih-alih merujuknya secara langsung.
Jika menerapkan alat berkualitas seperti SonarSource, ada aturan yang memaksa pengembang untuk menjatuhkan antarmuka konstan, ini adalah hal yang aneh karena banyak proyek menikmati antarmuka yang konstan dan jarang melihat hal-hal "memperluas" terjadi pada antarmuka yang konstan
sumber