Câu trả lời:
Java khó hiểu vì mọi thứ đều được truyền qua giá trị . Tuy nhiên, đối với một tham số của kiểu tham chiếu (nghĩa là không phải là tham số của kiểu nguyên thủy), chính tham chiếu được truyền theo giá trị, do đó nó dường như là tham chiếu qua (và mọi người thường cho rằng đó là tham chiếu). Đây không phải là trường hợp, như thể hiện dưới đây:
Object o = "Hello";
mutate(o)
System.out.println(o);
private void mutate(Object o) { o = "Goodbye"; } //NOT THE SAME o!
Sẽ in Hello
ra bàn điều khiển. Các tùy chọn nếu bạn muốn mã ở trên để in Goodbye
là sử dụng tham chiếu rõ ràng như sau:
AtomicReference<Object> ref = new AtomicReference<Object>("Hello");
mutate(ref);
System.out.println(ref.get()); //Goodbye!
private void mutate(AtomicReference<Object> ref) { ref.set("Goodbye"); }
Tôi có thể truyền tham số bằng tham chiếu trong Java không?
Không.
Tại sao ? Java chỉ có một chế độ truyền đối số cho các phương thức: theo giá trị.
Ghi chú:
Đối với người nguyên thủy, điều này rất dễ hiểu: bạn nhận được một bản sao của giá trị.
Đối với tất cả những người khác, bạn nhận được một bản sao của tài liệu tham khảo và điều này cũng được gọi là chuyển qua giá trị.
Đó là tất cả trong bức tranh này:
Trong Java không có gì ở cấp độ ngôn ngữ tương tự như ref . Trong Java chỉ có truyền qua ngữ nghĩa giá trị
Vì sự tò mò, bạn có thể triển khai một ngữ nghĩa giống như trong Java chỉ đơn giản là bọc các đối tượng của bạn trong một lớp có thể thay đổi:
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();
}
}
thử nghiệm:
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
(đối với người không nguyên thủy)? Hoặc AtomicSomething
(ví dụ AtomicBoolean
:) cho người nguyên thủy?
int
thay vì Integer
, bool
thay vì Boolean
và như vậy không? Đó là, các lớp bao bọc (được tự động mở ra nếu bạn lo lắng về cú pháp) không hoạt động?
Từ James Gosling trong "Ngôn ngữ lập trình Java":
"... Có chính xác một chế độ truyền tham số trong Java - truyền theo giá trị - và điều đó giúp mọi thứ đơn giản. .."
The pronouncement of the language god should be declared the answer
Không hẳn. Bất chấp những gì người tạo ra Java nghĩ hoặc tin, câu trả lời tuyệt đối sẽ đến từ một trích dẫn từ đặc tả ngôn ngữ.
Tôi không nghĩ bạn có thể. Tùy chọn tốt nhất của bạn có thể là gói gọn thứ bạn muốn chuyển "bằng ref" sang một thể hiện của lớp khác và truyền tham chiếu của lớp (bên ngoài) (theo giá trị). Nếu bạn hiểu ý tôi là ...
tức là phương thức của bạn thay đổi trạng thái bên trong của đối tượng mà nó được truyền, sau đó hiển thị cho người gọi.
Một tùy chọn khác là sử dụng một mảng, ví dụ:
void method(SomeClass[] v) { v[0] = ...; }
1) mảng phải được khởi tạo trước khi gọi phương thức, 2) vẫn không thể thực hiện ví dụ phương thức hoán đổi theo cách này ... Cách này được sử dụng trong JDK, ví dụ như trong java.util.concurrent.atomic.AtomicMarkableReference.get(boolean[])
.