Jawaban:
Java membingungkan karena semuanya dilewatkan oleh nilai . Namun untuk parameter tipe referensi (yaitu bukan parameter tipe primitif) itu adalah referensi itu sendiri yang dilewatkan oleh nilai, maka itu tampaknya menjadi pass-by-reference (dan orang sering mengklaim bahwa itu adalah). Ini tidak terjadi, seperti yang ditunjukkan oleh hal berikut:
Object o = "Hello";
mutate(o)
System.out.println(o);
private void mutate(Object o) { o = "Goodbye"; } //NOT THE SAME o!
Akan mencetak Hello
ke konsol. Opsi jika Anda ingin mencetak kode di atas Goodbye
adalah dengan menggunakan referensi eksplisit sebagai berikut:
AtomicReference<Object> ref = new AtomicReference<Object>("Hello");
mutate(ref);
System.out.println(ref.get()); //Goodbye!
private void mutate(AtomicReference<Object> ref) { ref.set("Goodbye"); }
Bisakah saya melewati parameter dengan referensi di Java?
Tidak.
Mengapa Java hanya memiliki satu mode meneruskan argumen ke metode: dengan nilai.
catatan:
Untuk primitif ini mudah dimengerti: Anda mendapatkan salinan nilainya.
Untuk semua yang lain Anda mendapatkan salinan referensi dan ini disebut juga lewat nilai.
Semuanya ada dalam gambar ini:
Di Jawa tidak ada pada tingkat bahasa yang mirip dengan ref . Di Jawa hanya ada yang lewat nilai semantik
Demi rasa ingin tahu Anda dapat menerapkan semantik seperti-ref di Jawa hanya membungkus objek Anda dalam kelas yang bisa berubah:
public class Ref<T> {
private T value;
public Ref(T value) {
this.value = value;
}
public T get() {
return value;
}
public void set(T anotherValue) {
value = anotherValue;
}
@Override
public String toString() {
return value.toString();
}
@Override
public boolean equals(Object obj) {
return value.equals(obj);
}
@Override
public int hashCode() {
return value.hashCode();
}
}
Kasus cobaan:
public void changeRef(Ref<String> ref) {
ref.set("bbb");
}
// ...
Ref<String> ref = new Ref<String>("aaa");
changeRef(ref);
System.out.println(ref); // prints "bbb"
AtomicReference
(untuk non-primitif)? Atau AtomicSomething
(misalnya AtomicBoolean
:) untuk primitif?
int
alih- alih Integer
, bool
bukannya Boolean
dan seterusnya? Yaitu, kelas wrapper (yang secara otomatis tidak terbuka jika Anda khawatir tentang sintaks) tidak berfungsi?
Dari James Gosling dalam "Bahasa Pemrograman Java":
"... Hanya ada satu mode passing parameter di Jawa - lulus dengan nilai - dan itu membuat semuanya menjadi sederhana ..."
The pronouncement of the language god should be declared the answer
Tidak juga. Terlepas dari apa yang dipikirkan atau diyakini oleh pencipta Jawa, jawaban absolut akan datang dari kutipan dari spesifikasi bahasa.
Saya pikir kamu tidak bisa. Pilihan terbaik Anda mungkin untuk merangkum hal yang ingin Anda sampaikan "dengan ref" ke instance kelas lain, dan meneruskan referensi kelas (luar) (berdasarkan nilai). Jika Anda melihat apa yang saya maksud ...
yaitu metode Anda mengubah keadaan internal objek yang dilewati, yang kemudian terlihat oleh pemanggil.
Opsi lain adalah menggunakan array, mis.
void method(SomeClass[] v) { v[0] = ...; }
Tetapi 1) array harus diinisialisasi sebelum metode dipanggil, 2) masih ada yang tidak dapat mengimplementasikan mis. Metode swap dengan cara ini ... Cara ini digunakan di JDK, misalnya dalam java.util.concurrent.atomic.AtomicMarkableReference.get(boolean[])
.