Periksa dua argumen di Jawa, keduanya tidak nol atau keduanya nol dengan elegan


161

Saya menggunakan spring boot untuk mengembangkan proyek shell yang digunakan untuk mengirim email, misalnya

sendmail -from foo@bar.com -password  foobar -subject "hello world"  -to aaa@bbb.com

Jika fromdan passwordargumen tidak ada, saya menggunakan pengirim dan kata sandi default, misalnya noreply@bar.comdan 123456.

Jadi, jika pengguna melewati fromargumen mereka juga harus melewati passwordargumen dan sebaliknya. Dengan kata lain, keduanya bukan nol, atau keduanya nol.

Bagaimana saya memeriksanya dengan elegan?

Sekarang jalan saya

if ((from != null && password == null) || (from == null && password != null)) {
    throw new RuntimeException("from and password either both exist or both not exist");
}

14
Sebagai tambahan, perhatikan bagaimana menggunakan spasi putih dengan hati-hati membuat kode jauh lebih mudah dibaca - hanya dengan menambahkan spasi antara operator dalam kode Anda saat ini akan secara signifikan menambah IMO keterbacaan.
Jon Skeet

8
Silakan tentukan "keanggunan".
Renaud

Anda memerlukan serangkaian argumen terpisah untuk kredensial otentikasi SMTP dan untuk alamat email pengirim amplop. The FromAlamat e-mail tidak selalu nama otentikasi SMTP.
Kaz

3
Ini benar-benar tidak bisa mendapatkan lebih banyak dioptimalkan, itu adalah satu baris kode yang dapat dibaca dan tidak ada yang bisa diperoleh dengan mengoptimalkannya secara berlebihan.
diynevala

3
Catatan: jika ini adalah skrip shell, bukankah kata sandi akan disimpan dalam riwayat shell?
sentuh tubuhku

Jawaban:


331

Ada cara menggunakan operator ^( XOR ):

if (from == null ^ password == null) {
    // Use RuntimeException if you need to
    throw new IllegalArgumentException("message");
}

The ifKondisi akan benar jika hanya satu variabel adalah null.

Tapi saya pikir biasanya lebih baik menggunakan dua ifkondisi dengan pesan pengecualian yang berbeda. Anda tidak dapat menentukan apa yang salah dengan menggunakan satu kondisi.

if ((from == null) && (password != null)) {
    throw new IllegalArgumentException("If from is null, password must be null");
}
if ((from != null) && (password == null)) {
    throw new IllegalArgumentException("If from is not null, password must not be null");
}

Ini lebih mudah dibaca dan jauh lebih mudah dipahami, dan hanya perlu sedikit mengetik tambahan.


152
Apakah ada alasan mengapa xor pada dua bools lebih disukai daripada !=pada dua bools?
Eric Lippert

1
Wow, saya tidak menyadari bahwa XOR pada boolean sama dengan !=. Mindblown. Dan itu adalah jumlah upvote yang sangat tinggi dalam komentar. Dan, untuk menambah kualitas komentar ini, ya, saya juga berpikir bahwa memberikan pesan kesalahan yang berbeda untuk kasus kesalahan yang berbeda lebih baik, karena pengguna akan lebih tahu cara memperbaiki kesalahan.
justhalf

1
Untuk 2 elemen baik-baik saja. Bagaimana melakukan ini dengan> 2 elemen?
Anushree Acharjee

Saya ingin menampilkan pesan kesalahan jika salah satu elemen> 0. Secara default semua diatur ke 0. Jika semua> 0 itu skenario yang valid. Bagaimana cara melakukannya?
Anushree Acharjee

Ini akan membuat pertanyaan wawancara yang bagus. Saya ingin tahu apa yang% programmer tahu. Tetapi saya tidak setuju bahwa itu tidak cukup jelas dan menjamin pemisahan menjadi 2 ifklausa - pesan dalam pengecualian mendokumentasikannya dengan baik (saya mengedit pertanyaan, tetapi tidak akan muncul sampai diterima)
Adam

286

Yah, sepertinya Anda mencoba memeriksa apakah kondisi "nullity" keduanya sama atau tidak. Anda bisa menggunakan:

if ((from == null) != (password == null))
{
    ...
}

Atau membuatnya lebih eksplisit dengan variabel pembantu:

boolean gotFrom = from != null;
boolean gotPassword = password != null;
if (gotFrom != gotPassword)
{
    ...
}

18
Anda adalah salah satu pahlawan SO @Kaz saya, tetapi tidak ada yang mengatakan 'ini atau itu, tetapi tidak keduanya sama' seperti ^halnya. :-)
David Bullock

6
@ Davidvidullock: Ketika datang ke Boolean, tidak ada yang mengatakan "ini atau itu tetapi tidak keduanya sama" seperti ... "tidak keduanya sama"; XOR adalah nama lain untuk "tidak sama dengan" fungsi lebih Booleans.
Kaz

5
@ Ka Hanya ^mengatakan "Hei, operan saya adalah boolean" dengan cara yang !=tidak. (Walaupun efek ini sayangnya berkurang karena kebutuhan untuk memeriksa "operan saya mungkin numerik, dan saya mungkin tidak menjadi operator relasional pada saat ini", yang saya berikan adalah kerugian). Status pahlawan Anda tidak berkurang, meskipun tidak setuju dengan saya :-)
David Bullock

3
Setelah membaca persyaratan masalah, lalu solusi Anda, kodenya masuk akal dan dapat dibaca. Tetapi sebagai pengembang selama 4 tahun (masih bersekolah), membaca kode ini kemudian mencoba mencari tahu apa "persyaratan bisnis" yang ada akan menjadi sakit kepala. Dari kode ini, saya tidak langsung mengerti " fromdan passwordkeduanya harus nol atau keduanya bukan nol". Mungkin itu hanya saya dan pengalaman saya, tapi saya lebih suka solusi yang lebih mudah dibaca seperti pada jawaban @ stig-hemmer, bahkan jika biaya 3 baris kode lain. Saya kira saya tidak segera mengerti bool != bool - itu tidak intuitif.
Chris Cirefice

2
@ Davidvider ^Operator adalah operator bitwise; sebenarnya tidak menyiratkan bahwa operan-nya adalah boolean. Operator boolean xor adalah xor.
Brilliand

222

Secara pribadi, saya lebih suka dibaca daripada elegan.

if (from != null && password == null) {
    throw new RuntimeException("-from given without -password");
}
if (from == null && password != null) {
    throw new RuntimeException("-password given without -from");
}

52
+1 untuk pesan yang lebih baik. Ini adalah penting, tidak ada yang gemar handwaving "sesuatu yang tidak beres" pesan -error, sehingga tak seorang pun harus menyebabkan pesan tersebut. Namun, dalam praktiknya, seseorang harus lebih memilih pengecualian yang lebih spesifik (khususnya, IllegalArgumentExceptionbukannya telanjang RuntimeException)
Marco13

6
@ Matt sepertinya kritik Anda tidak dengan kode, tetapi dengan teks pengecualian. Tapi saya pikir manfaat dari jawaban ini terletak pada struktur pernyataan if, bukan pada isi pesan kesalahan. Ini adalah jawaban terbaik karena meningkatkan fungsionalitas; OP dapat dengan mudah mengganti string apa pun yang mereka suka dengan teks pengecualian.
Dan Henderson

4
@matt Keuntungannya adalah menjadi mungkin untuk membedakan mana dari dua keadaan tidak valid yang telah terjadi, dan menyesuaikan pesan kesalahan. Jadi, alih-alih mengatakan "Anda telah melakukan salah satu dari dua hal ini salah," Anda dapat mengatakan "Anda melakukan ini" atau "Anda melakukan itu" (dan kemudian melanjutkan untuk memberikan langkah-langkah penyelesaian, jika diinginkan). Resolusi mungkin sama dalam kedua kasus, tetapi tidak pernah merupakan ide yang baik untuk mengatakan "Anda melakukan salah satu dari hal-hal ini salah". Sumber: di lingkungan di mana saya tidak dapat menyediakan fungsionalitas ini, saya menerjunkan banyak pertanyaan dari pengguna yang memenuhi syarat pertama dalam teks kesalahan saya.
Dan Henderson

4
@DanHenderson> tidak pernah merupakan ide yang baik untuk mengatakan "Anda salah melakukan hal-hal ini." Saya tidak setuju. Kata sandi / nama pengguna itu lebih aman untuk hanya mengatakan nama pengguna dan kata sandi tidak cocok.
matt

2
@DanHenderson Dari sudut pandang keamanan, mungkin lebih baik tidak membedakan antara kasus di mana nama pengguna berada di direktori atau tidak karena jika tidak seorang penyerang bisa mengetahui nama pengguna yang valid. Namun, pencampuran null / bukan null adalah (dalam hal ini) selalu merupakan kesalahan penggunaan dan menunjukkan pesan kesalahan yang lebih terperinci tidak membocorkan informasi lebih banyak daripada yang diberikan pengguna sejak awal.
siegi

16

Masukkan fungsi itu dalam metode 2 argumen dengan tanda tangan:

void assertBothNullOrBothNotNull(Object a, Object b) throws RuntimeException

Ini menghemat ruang dalam metode aktual yang Anda minati dan membuatnya lebih mudah dibaca. Tidak ada yang salah dengan nama metode yang sedikit verbose dan tidak ada yang salah dengan metode yang sangat pendek.


14
Tidak ada ruang yang disimpan vs ((from == null) != (password == null))yang sangat sederhana untuk dipahami juga. Ada yang salah dengan metode yang tidak berguna.
edc65

3
Ada satu baris untuk pernyataan if, baris kedua untuk pernyataan melempar dan baris ketiga untuk penjepit penutup: Semua diganti dengan satu baris. Satu lagi garis disimpan jika Anda memberi kawat gigi penutup sebuah garis baru!
Traubenfuchs

10
Saat membaca kode Anda memiliki satu nama metode yang perlu Anda pahami vs juggling kondisi.
Traubenfuchs

1
pasti +1, selalu lebih suka mengabstraksi rincian implementasi dan operator yang jauh-dan-kotor dengan metode deskriptif dan nama variabel yang membuat INTENTION jelas. logika berisi bug. komentar bahkan lebih buruk. nama metode menunjukkan niat dan mengisolasi logika sehingga lebih mudah untuk menemukan dan memperbaiki kesalahan. solusi ini tidak mengharuskan pembaca untuk mengetahui atau berpikir tentang sintaks atau logika sama sekali, itu memungkinkan kita untuk fokus pada PERSYARATAN BISNIS sebagai gantinya (yang merupakan hal yang sangat penting)
sara

1
Anda akan mengalami masalah yang tidak perlu jika Anda ingin memiliki pesan pengecualian deskriptif di sini.
Honza Brabec

11

Solusi Java 8 akan digunakan Objects.isNull(Object), dengan asumsi impor statis:

if (isNull(from) != isNull(password)) {
    throw ...;
}

Untuk Java <8 (atau jika Anda tidak suka menggunakan Objects.isNull()), Anda dapat dengan mudah menulis isNull()metode Anda sendiri .


6
Tidak suka itu from == null != password == nullmenyimpan semuanya pada frame yang sama dari stack, tetapi menggunakan Objects.isNull(Object)push dan pops dua frame yang tidak perlu. Objects.isNull (Object) ada di sana karena 'Metode ini ada untuk digunakan sebagai Predikat' (mis. Dalam aliran).
David Bullock

5
Metode sederhana seperti ini biasanya akan cepat diuraikan oleh JIT sehingga dampak kinerja kemungkinan besar dapat diabaikan. Kita memang bisa memperdebatkan penggunaan Objects.isNull()- Anda dapat menulis sendiri jika Anda mau - tetapi sejauh menyangkut keterbacaan saya pikir menggunakan isNull()lebih baik. Selain itu Anda perlu kurung tambahan untuk membuat sederhana ekspresi kompilasi: from == null != (password == null).
Didier L

2
Saya setuju tentang JIT'ing (dan urutan operasi ... Saya malas). Namun, (val == null)begitu sangat banyak fasilitas yang disediakan untuk tujuan membandingkan dengan nol, saya merasa sulit untuk mendapatkan lebih dari dua besar metode lemak doa menatap saya di wajah, bahkan jika metode ini cukup fungsional, di-lineable, dan dengan baik bernama. Tapi itu hanya aku. Baru-baru ini saya memutuskan bahwa saya aneh.
David Bullock

4
jujur, siapa yang peduli tentang satu tumpukan bingkai? tumpukan hanya menjadi masalah jika Anda berurusan dengan rekursi (mungkin tak terbatas), atau jika Anda memiliki aplikasi 1000-tier dengan objek grafik ukuran gurun sahara.
sara

9

Berikut ini adalah solusi umum untuk sejumlah cek nol

public static int nulls(Object... objs)
{
    int n = 0;
    for(Object obj : objs) if(obj == null) n++;
    return n;
}

public static void main (String[] args) throws java.lang.Exception
{
    String a = null;
    String b = "";
    String c = "Test";

    System.out.println (" "+nulls(a,b,c));
}

Penggunaan

// equivalent to (a==null & !(b==null|c==null) | .. | c==null & !(a==null|b==null))
if (nulls(a,b,c) == 1) { .. }

// equivalent to (a==null | b==null | c==null)
if (nulls(a,b,c) >= 1) { .. }

// equivalent to (a!=null | b!=null | c!=null)
if (nulls(a,b,c) < 3) { .. }

// equivalent to (a==null & b==null & c==null)
if (nulls(a,b,c) == 3) { .. }

// equivalent to (a!=null & b!=null & c!=null)
if (nulls(a,b,c) == 0) { .. }

2
Pendekatan yang baik, tetapi komentar "setara" pertama Anda sangat salah (di luar kesalahan ejaan yang ada di semua komentar)
Ben Voigt

@ BenVoigt Terima kasih atas pemberitahuannya, perbaiki sekarang
Khaled.K

9

Karena Anda ingin melakukan sesuatu yang istimewa (gunakan default) ketika pengirim dan kata sandi tidak ada, tangani terlebih dahulu.
Setelah itu, Anda harus memiliki pengirim dan kata sandi untuk mengirim email; lempar pengecualian jika salah satu tidak ada.

// use defaults if neither is provided
if ((from == null) && (password == null)) {
    from = DEFAULT_SENDER;
    password = DEFAULT_PASSWORD;
}

// we should have a sender and a password now
if (from == null) {
    throw new MissingSenderException();
}
if (password == null) {
    throw new MissingPasswordException();
}

Manfaat tambahan adalah bahwa, jika salah satu dari default Anda menjadi nol, itu akan terdeteksi juga.


Karena itu, secara umum saya berpikir bahwa penggunaan XOR harus diizinkan ketika itu adalah operator yang Anda butuhkan. Ini adalah bagian dari bahasa, bukan hanya beberapa trik yang bekerja karena bug-compiler misterius.
Saya pernah punya sapi-orker yang menemukan operator ternary terlalu membingungkan untuk digunakan ...


1
Tunduk karena saya membuat pilihan acak untuk mengambil sampel dari salah satu jawaban Anda dan tidak dapat menemukan tautan xkcd yang dijanjikan! tidak tahu malu!
dhein

@Zaibis Dalam pembelaan saya, itu hanya hobi, bukan pekerjaan penuh waktu. Tetapi saya akan melihat apakah saya dapat menemukannya ...
SQB

8

Saya ingin menyarankan alternatif lain yaitu bagaimana saya benar-benar menulis potongan kode ini:

if( from != null )
{
    if( password == null )
        error( "password required for " + from );
}
else
{
    if( password != null )
        warn( "the given password will not be used" );
}

Bagi saya ini sepertinya cara paling alami untuk mengekspresikan kondisi ini yang membuatnya mudah dimengerti bagi seseorang yang mungkin harus membacanya di masa depan. Hal ini juga memungkinkan Anda untuk memberikan pesan diagnostik yang lebih bermanfaat dan memperlakukan kata sandi yang tidak perlu sebagai kurang serius dan membuatnya mudah untuk memodifikasi yang agak mungkin untuk kondisi seperti itu. Yaitu, Anda mungkin mengetahui bahwa memberikan kata sandi sebagai argumen baris perintah bukanlah ide terbaik dan mungkin ingin membolehkan membaca kata sandi dari input standar secara opsional jika argumen tersebut tidak ada. Atau Anda mungkin ingin mengabaikan argumen kata sandi berlebihan secara diam-diam. Perubahan seperti ini tidak mengharuskan Anda untuk menulis ulang semuanya.

Selain itu hanya menjalankan perbandingan minimum, sehingga tidak lebih mahal daripada alternatif yang lebih "elegan" . Meskipun kinerja sangat tidak mungkin menjadi masalah di sini karena memulai proses baru sudah jauh lebih mahal daripada pemeriksaan nol tambahan.


Saya berkomentar agak percakapan, jadi saya bisa mengikuti yang lain dengan "// kita punya nol dari". Singkatnya contoh membuat ini sangat kecil. Saya sangat menyukai kejelasan logika dan pengurangan tes yang disajikan ini.
The Nate

Ini bekerja dengan sangat baik, tetapi bersarang jika pernyataan tampak kurang jelas dan lebih berantakan bagi saya. Itu hanya pendapat pribadi, jadi saya senang jawaban ini ada di sini sebagai pilihan lain
Kevin Wells

Sejauh keanggunan, ini mungkin salah satu cara yang paling tidak elegan untuk melakukan ini.
dramzy

7

Saya pikir cara yang tepat untuk menangani ini adalah dengan mempertimbangkan tiga situasi: baik 'dari' dan 'kata sandi' disediakan, tidak ada yang disediakan, campuran keduanya disediakan.

if(from != null && password != null){
    //use the provided values
} else if(from == null && password == null){
    //both values are null use the default values
} else{
   //throw an exception because the input is not correct.
}

Kedengarannya seperti pertanyaan asli yang ingin memutus aliran jika inputnya salah, tetapi kemudian mereka harus mengulang beberapa logika nanti. Mungkin pernyataan lemparan yang baik mungkin:

throw new IllegalArgumentException("form of " + form + 
    " cannot be used with a "
    + (password==null?"null":"not null") +  
    " password. Either provide a value for both, or no value for both"
);

2
Kode ini salah bukan karena tidak berfungsi tetapi karena sangat sulit dimengerti. Men-debug kode semacam itu, yang ditulis oleh orang lain, hanyalah mimpi buruk.
NO_NAME

2
@NO_NAME Saya tidak mengerti mengapa ini sulit dimengerti. OP menyediakan tiga kasus: Ketika kedua bentuk dan kata sandi diberikan, ketika tidak ada yang disediakan, dan campuran kasus yang harus mengeluarkan pengecualian. Apakah Anda mengacu pada persyaratan tengah untuk memeriksa apakah keduanya nol?
matt

2
Saya setuju dengan @NO_NAME, kasing tengah itu membutuhkan terlalu banyak penguraian untuk dilirik. Kecuali Anda menguraikan baris atas, Anda tidak mendapatkan bahwa nol itu ada hubungannya dengan tengah. Kesetaraan dari dan kata sandi dalam kasus itu sebenarnya hanyalah efek samping dari tidak menjadi nol.
jimm101

1
@ jimm101 Ya, saya bisa melihat itu menjadi masalah. Manfaat kinerja akan minimal / tidak terdeteksi untuk solusi yang lebih bertele-tele. Saya tidak yakin apakah itu masalahnya. Saya akan memperbaruinya.
matt

2
@matt Mungkin tidak ada manfaat kinerja - tidak jelas apa yang akan dilakukan kompiler, dan apa yang akan diambil chip dari memori dalam kasus ini. Banyak siklus programmer dapat dibakar pada optimasi yang tidak benar-benar menghasilkan apa pun.
jimm101

6

Berikut ini adalah cara yang relatif lurus ke depan yang tidak melibatkan Xor dan waktu panjang. Namun itu mengharuskan Anda untuk sedikit lebih bertele-tele, tetapi pada terbalik, Anda dapat menggunakan Pengecualian khusus yang saya sarankan untuk mendapatkan pesan kesalahan yang lebih bermakna.

private void validatePasswordExists(Parameters params) {
   if (!params.hasKey("password")){
      throw new PasswordMissingException("Password missing");
   }
}

private void validateFromExists(Parameters params) {
   if (!params.hasKey("from")){
      throw new FromEmailMissingException("From-email missing");
   }
}

private void validateParams(Parameters params) {

  if (params.hasKey("from") || params.hasKey("password")){
     validateFromExists(params);
     validatePasswordExists(params);
  }
}

1
Anda tidak harus menggunakan pengecualian sebagai pengganti pernyataan aliran kontrol. Selain menjadi hit kinerja, yang lebih penting itu mengurangi keterbacaan kode Anda karena itu merusak aliran mental.
an phu

1
@ anphu Tidak. Hanya tidak. Menggunakan pengecualian meningkatkan keterbacaan kode karena menghilangkan klausa if-else dan membuat aliran kode lebih jelas. docs.oracle.com/javase/tutorial/essential/exceptions/…
Arnab Datta

1
Saya pikir Anda membingungkan sesuatu yang benar-benar luar biasa vs sesuatu yang terjadi secara rutin dan dapat dianggap sebagai bagian dari eksekusi normal. Dokumen java menggunakan contoh yang luar biasa yaitu kehabisan memori saat membaca file; Menghadapi param yang tidak valid tidak luar biasa. "Jangan gunakan pengecualian untuk aliran kontrol normal." - blogs.msdn.com/b/kcwalina/archive/2005/03/16/396787.aspx
an phu

Nah, pertama: jika argumen yang hilang / tepat tidak luar biasa, mengapa IllegalArgumentException bahkan ada? Kedua: jika Anda benar-benar percaya bahwa argumen yang tidak valid tidak luar biasa, maka seharusnya tidak ada validasinya juga. Dengan kata lain, coba saja lakukan tindakan dan ketika terjadi kesalahan, maka lempar pengecualian. Pendekatan ini baik-baik saja, tetapi hukuman kinerja yang Anda bicarakan terjadi di sini, bukan dalam pendekatan yang saya sarankan. Pengecualian Java tidak lambat saat dilempar; itu stacktrace yang membutuhkan waktu untuk pulih.
Arnab Datta

Konteks adalah kuncinya. Dalam konteks OP (aplikasi sendmail), melupakan nama pengguna dan kata sandi adalah hal yang umum dan diharapkan. Dalam panduan kendali rudal, param koordinat nol harus mengeluarkan pengecualian. Saya tidak mengatakan jangan memvalidasi params. Dalam konteks OP, saya katakan jangan gunakan pengecualian untuk mengarahkan logika aplikasi. Mengurai stacktrace adalah hit perf yang saya bicarakan. Dengan menggunakan pendekatan Anda, pada akhirnya Anda dapat menangkap PasswordMissingException / FromEmailMissingException yaitu melepas, atau lebih buruk, membiarkannya tidak ditangani. .
sebuah phu

6

Sepertinya tidak ada yang menyebut operator ternary :

if (a==null? b!=null:b==null)

Bekerja dengan baik untuk memeriksa kondisi khusus ini, tetapi tidak menyamaratakan melewati dua variabel.


1
Terlihat bagus, tetapi lebih sulit dimengerti daripada ^, !=dengan dua bools atau dua ifs
coolguy

@coolguy Dugaan saya adalah bahwa operator ternary jauh lebih umum daripada operator XOR (belum lagi 'kejutan mental' setiap kali Anda melihat XOR dalam kode yang tidak melakukan operasi bit), dan formulasi ini cenderung menghindari pemotongan dan rekatkan kesalahan yang mengganggu gandakan jika.
gbronner

Tidak direkomendasikan. Ini tidak akan membedakan antara (a! = Null && b == null) dan (a == null && b! = Null). Jika Anda akan menggunakan operator ternary:a == null ? (b == null? "both null" : "a null while b is not") : (b ==null? "b null while a is not")
Arnab Datta

5

Seperti yang saya lihat niat Anda, tidak perlu selalu memeriksa kedua nullities eksklusif tetapi untuk memeriksa apakah passworditu null jika dan hanya jika fromtidak nol. Anda dapat mengabaikan passwordargumen yang diberikan dan menggunakan default Anda sendiri jikafrom nol.

Ditulis dalam pseudo harus seperti ini:

if (from == null) { // form is null, ignore given password here
    // use your own defaults
} else if (password == null) { // form is given but password is not
    // throw exception
} else { // both arguments are given
    // use given arguments
}

4
Satu-satunya masalah dengan ini adalah bahwa ketika pengguna memasok passwordtanpa memasok from, maka mereka mungkin bermaksud untuk menimpa kata sandi, tetapi tetap menggunakan akun default. Jika pengguna melakukan itu, itu adalah instruksi yang tidak valid dan mereka harus diberitahu demikian. Program tidak boleh melanjutkan seolah-olah inputnya valid, dan teruskan dan coba gunakan akun default dengan kata sandi yang tidak ditentukan pengguna. Saya bersumpah pada program seperti itu.
David Bullock

4

Saya terkejut tidak ada yang menyebutkan solusi sederhana membuat fromdan passwordbidang kelas dan memberikan referensi ke contoh kelas itu:

class Account {
    final String name, password;
    Account(String name, String password) {
        this.name = Objects.requireNonNull(name, "name");
        this.password = Objects.requireNonNull(password, "password");
    }
}

// the code that requires an account
Account from;
// do stuff

Sini from bisa nol atau non-nol dan jika bukan nol, kedua bidangnya memiliki nilai bukan nol.

Salah satu keuntungan dari pendekatan ini adalah bahwa kesalahan membuat satu bidang tetapi bukan bidang lain nol dipicu di mana akun awalnya diperoleh, bukan ketika kode menggunakan akun berjalan. Pada saat kode menggunakan akun dieksekusi, data tidak mungkin menjadi tidak valid.

Keuntungan lain dari pendekatan ini lebih mudah dibaca karena memberikan lebih banyak informasi semantik. Juga, kemungkinan Anda memerlukan nama dan kata sandi bersama di tempat lain sehingga biaya untuk menentukan kelas tambahan diamortisasi selama beberapa penggunaan.


Itu tidak berfungsi seperti yang diharapkan karena new Account(null, null)akan melempar NPE meskipun Akun dengan nama dan kata sandi nol masih valid.
HieuHT

Idenya adalah untuk lulus nol jika nama dan kata sandi adalah nol, apakah atau tidak di dunia nyata Anda akan mengatakan akun itu ada.
Pasang kembali Monica

Apa yang saya dapatkan dari OP adalah Artinya, baik keduanya non-nol, atau keduanya nol. Saya hanya ingin tahu bagaimana Anda dapat membuat objek Akun dengan nama dan kata sandi nol?
HieuHT

@HieuHT Maaf komentar terakhir saya tidak jelas. Jika nama dan kata sandi adalah nol, Anda akan menggunakan nullbukan Account. Anda tidak akan lolos nullke Accountkonstruktor.
Pasang kembali Monica
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.