Bagaimana beberapa nilai dikembalikan di Jawa?

11

Terkadang Anda ingin mengembalikan beberapa nilai dari suatu fungsi. Bagaimana ini biasanya dilakukan di Jawa?

Salah satu opsi adalah menggunakan array, seperti cuplikan Python ini yang mengembalikan daftar atau tuple:

value, success = read_unreliably()
if success:
    print value

Opsi lain adalah mengembalikan hash / dict, seperti contoh JavaScript ini:

var result = readUnreliably()
if (result.success) {
    alert(value);
}

Satu lagi adalah membuat objek khusus hanya untuk tujuan ini, seperti contoh Java ini:

ReadUnreliablyResult result = readUnreliably()
if (result.getSuccess()) {
    System.out.println(result.getValue());
}

Tentu saja Anda juga dapat hanya menggunakan beberapa variabel global untuk menyimpan apa yang Anda butuhkan alih-alih membagikannya, tetapi katakan saja itu bukan pilihan.

Mike M. Lin
sumber
Apakah orang java "nyata" benar-benar mengalami kesulitan menggunakan getter publik dan setter untuk menyembunyikan bidang pada kelas internal kecil seperti itu? Hanya penasaran.
Chris Farmer
3
Ya, kebanyakan. Karena banyak kerangka kerja mengharapkan standar JavaBean, Anda dapat menyesal tidak memiliki getter dan setter. Bagaimanapun, IDE Anda akan membuatnya untuk Anda.
Eric Wilson
3
Atau Anda bisa mengabaikannya, berdasarkan prinsip YAGNI. Tapi itu sepertinya tidak terjadi sesering yang diharapkan.
MatrixFrog
@FarmBoy: Saya kira saya mengerti untuk kacang dan semacamnya, tetapi OP menyiratkan bahwa ini hanya kelas satu kali yang dirancang untuk mengembalikan beberapa nilai.
Chris Farmer
@ ChrisFarmer Saya kira dengan konteks itu, saya belum pernah melihat programmer Java 'nyata' membuat kelas untuk tujuan ini.
Eric Wilson

Jawaban:

26

Bagaimana ini biasanya dilakukan di Jawa?

Menyakitkan.

Salah satu opsi adalah menggunakan array, seperti cuplikan Python ini yang mengembalikan daftar atau tuple ...

Pilihan lain adalah mengembalikan hash / dict, seperti contoh JavaScript ini ...

Teknik-teknik ini tidak berfungsi dengan baik di Jawa; nilai-nilai harus diturunkan dari Object.

Satu lagi adalah membuat objek khusus hanya untuk tujuan ini, seperti contoh Java ini ...

Ini paling umum, tapi membosankan untuk membuat semua kelas kecil itu. Di C ++ biasanya menggunakan std :: pair tetapi ini tidak umum dilakukan di Java.

Dengan Lombok , cukup mudah untuk membuat objek khusus kecil:

@RequiredArgsConstructor
public class X {
  private final boolean status;
  private final byte[] data;

}

kevin cline
sumber
10
"Bagaimana ini biasanya dilakukan di Jawa?" "Dengan menyakitkan." lol sebagai pengembang Java saya harus memberi Anda +1 untuk itu
TheLQ
Menggunakan kelas struct-like immutable yang kompak tidak begitu menyakitkan ... Ini benar-benar seperti menulis struct C ...
Guillaume
1
@Guillaume - tentu saja, tetapi semua hal kecil itu bertambah baik dalam ruang dan waktu. Saya tidak tahu mengapa komunitas Java belum mengadopsi serangkaian standar generik seperti "Pair kelas <T1, T2> {public T1 first; public T2 second; ...}"; dalam bahasa modern Anda hanya "mengembalikan a, b"; dan kemudian tulis "x, y = f ()";
kevin cline
1
Saya yakin beberapa bahasa 'kuno' dapat melakukannya juga :) IMHO saya menemukan beberapa nilai kembali dapat menyebabkan kekacauan total, dan jika Anda perlu menambahkan bidang kembali lainnya, Anda hanya perlu memperbarui struct seperti kelas tanpa harus ubah tanda tangan metode Anda.
Guillaume
1
"Itu menyakitkan." saya sangat terpukul, ya itu persis apa yang saya rasakan sebagai pengembang Java ketika saya bertemu situasi yang sama.
artjom
13

Ya, cara membuat struct/ tuple/ recorddi Java adalah dengan membuat kelas. Jika hanya untuk penggunaan internal, saya lebih suka menggunakan kelas struct-like yang tidak bisa diubah dengan bidang publik.

Contoh:

public class Unreliably {
    public final boolean success;
    public final int value;
    public Unreliably(boolean success, int value) {
        this.success = success; this.value = value;
    }
}

Ini jauh lebih mudah dilakukan di Scala:

case class Unreliably(success: Boolean, value: Int)
Jonas
sumber
8
Sebenarnya, di Scala, Anda mungkin umumnya hanya mengembalikan a Tuple2[Boolean, Int]. Meskipun dalam contoh khusus ini , Anda akan mengembalikan Option[Int].
Jörg W Mittag
2
Jadi ini menjawab pertanyaan Chris Farmer (dalam komentar Q) bahwa orang Jawa nyata tidak perlu membuat getter dan setter untuk kelas internal kecil. Anda adalah orang Jawa "asli", bukan?
Mike M. Lin
2
Di berita lain, tidak ada orang Skotlandia sejati.
Joseph Weissman
5

Sebagai contoh yang Anda berikan, melemparkan pengecualian akan menjadi cara paling standar untuk menanganinya:

try {
    result = readUnreliably();
    System.out.println(result);
} (catch IOException e) {
    System.out.println("Could not read file");
}

Selain itu, jika Anda berusaha untuk memiliki fungsi yang "Do One Thing" fitur mengembalikan beberapa nilai kurang diperlukan, meskipun kadang-kadang nyaman.

Eric Wilson
sumber
4

Kami memiliki kelas generik Pair yang dapat menyimpan satu instance A dan satu instance B. Anda mungkin dapat membuat Triplet atau Quadruplet dengan cara yang sama.

public class Pair<A, B>
{
    ...
}
Raku
sumber
1
ini membuat beberapa kode yang SANGAT tidak dapat dibaca. jika suatu metode kembali Pair<String, Integer>, apa artinya itu? apa yang mewakili nilai-nilai ini? Anda tidak mungkin tahu tanpa membaca implementasi metode ini.
sara
1

Di Jawa, fungsi Anda akan mengembalikan objek (atau mungkin nol jika terjadi kegagalan). Dengan cara ini, beberapa bagian data dapat dikembalikan.

Scott C Wilson
sumber
1

Tidak ada cara eksplisit untuk mengembalikan beberapa variabel di Jawa, namun ada beberapa pendekatan:

  1. Yang pertama adalah pergi jalan array. Ini hanya benar-benar berfungsi jika Anda memiliki semuanya sebagai tipe data yang sama atau dapat sementara mengonversinya menjadi satu jenis.
  2. Cara kedua adalah membuat kelas untuk tujuan mentransfer beberapa tipe variabel. Di pekerjaan saya, kami menyebutnya sebagai DTO atau Objek Transfer Data.

sumber