ฉันต้องการความหมายคล้ายกับC#
's ref
คำหลัก
ฉันต้องการความหมายคล้ายกับC#
's ref
คำหลัก
คำตอบ:
Java เป็นความสับสนเพราะทุกอย่างจะผ่านค่า อย่างไรก็ตามสำหรับพารามิเตอร์ของประเภทการอ้างอิง (เช่นไม่ใช่พารามิเตอร์ของประเภทดั้งเดิม) มันเป็นการอ้างอิงตัวเองซึ่งถูกส่งผ่านตามค่าดังนั้นจึงปรากฏว่าเป็นการส่งต่อโดยอ้างอิง (และผู้คนมักอ้างว่าเป็น) นี่ไม่ใช่กรณีดังแสดงโดยต่อไปนี้:
Object o = "Hello";
mutate(o)
System.out.println(o);
private void mutate(Object o) { o = "Goodbye"; } //NOT THE SAME o!
จะพิมพ์Hello
ไปที่คอนโซล ตัวเลือกหากคุณต้องการให้โค้ดด้านบนเพื่อพิมพ์Goodbye
นั้นใช้การอ้างอิงที่ชัดเจนดังต่อไปนี้:
AtomicReference<Object> ref = new AtomicReference<Object>("Hello");
mutate(ref);
System.out.println(ref.get()); //Goodbye!
private void mutate(AtomicReference<Object> ref) { ref.set("Goodbye"); }
ฉันสามารถส่งพารามิเตอร์โดยอ้างอิงใน Java ได้หรือไม่
เลขที่
ทำไม Java มีเพียงหนึ่งโหมดของการส่งผ่านข้อโต้แย้งไปยังวิธีการ: ตามค่า
บันทึก:
สำหรับสิ่งพื้นฐานสิ่งนี้เข้าใจง่าย: คุณได้รับสำเนาของค่า
สำหรับคนอื่น ๆ คุณจะได้รับสำเนาของการอ้างอิงและสิ่งนี้เรียกว่ายังผ่านค่า
มันคือทั้งหมดในภาพนี้:
ใน Java มีอะไรในระดับภาษาคล้ายกับโทษ ใน Java มีเพียงความหมายผ่านค่า
เพื่อความอยากรู้อยากเห็นคุณสามารถใช้ความหมายอ้างอิงในภาษาจาวาเพียงห่อวัตถุของคุณในคลาสที่ไม่แน่นอน
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();
}
}
testcase:
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
(สำหรับผู้ที่ไม่ใช่พื้นฐาน)? หรือAtomicSomething
(เช่นAtomicBoolean
:) สำหรับดั้งเดิม?
int
แทนInteger
, bool
แทนBoolean
และอื่น ๆ ? นั่นคือคลาสของ wrapper (ซึ่งจะถูกคลายโดยอัตโนมัติหากคุณกังวลเกี่ยวกับไวยากรณ์) ไม่ทำงาน?
จาก James Gosling ใน "ภาษาการเขียนโปรแกรม Java":
"... มีโหมดการผ่านพารามิเตอร์หนึ่งตัวใน Java - ผ่านค่า - และนั่นทำให้สิ่งต่าง ๆ ง่ายขึ้น .. "
The pronouncement of the language god should be declared the answer
ไม่จริงหรอก แม้จะมีสิ่งที่ผู้สร้างของ Java คิดหรือเชื่อคำตอบที่แน่นอนจะมาจากคำพูดจากสเปคภาษา
ฉันไม่คิดว่าคุณจะทำได้ ตัวเลือกที่ดีที่สุดของคุณอาจจะแค็ปซูลสิ่งที่คุณต้องการผ่าน "โดยอ้างอิง" ไปยังอินสแตนซ์ของคลาสอื่นและส่งผ่านการอ้างอิงของคลาส (ภายนอก) (ตามค่า) ถ้าคุณเห็นสิ่งที่ฉันหมายถึง ...
เช่นวิธีการของคุณเปลี่ยนสถานะภายในของวัตถุที่มีการส่งผ่านซึ่งจะปรากฏแก่ผู้โทร
Java ผ่านค่าเสมอ
เมื่อคุณผ่านการดั้งเดิมมันเป็นสำเนาของค่าเมื่อคุณผ่านวัตถุมันเป็นสำเนาของตัวชี้การอ้างอิง
อีกตัวเลือกหนึ่งคือการใช้อาร์เรย์เช่น
void method(SomeClass[] v) { v[0] = ...; }
แต่ 1) อาร์เรย์จะต้องเริ่มต้นก่อนที่จะใช้วิธีการเรียก 2) ยังคงเป็นหนึ่งไม่สามารถใช้วิธีการแลกเปลี่ยนเช่นในทางนี้ ... วิธีนี้จะใช้ใน JDK java.util.concurrent.atomic.AtomicMarkableReference.get(boolean[])
เช่นใน