如何让 Java 赋值指向一个对象而不是复制?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2776145/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can Java assignment be made to point to an object instead of making a copy?
提问by Matthew Piziak
In a class, I have:
在课堂上,我有:
private Foo bar;
public Constructor(Foo bar)
{
this.bar = bar;
}
Instead of creating a copy of bar from the object provided in the parameter, is it possible to include a pointer to bar in the constructor such that changing the original bar changes the field in this object?
不是从参数中提供的对象创建 bar 的副本,是否可以在构造函数中包含指向 bar 的指针,以便更改原始 bar 会更改此对象中的字段?
Another way of putting it:
另一种表达方式:
int x = 7;
int y = x;
x = 9;
System.out.print(y); //Prints 7.
It is possible to set it up so that printing y prints 9 instead of 7?
是否可以设置它以便打印 y 打印 9 而不是 7?
采纳答案by leonbloy
Your last example works that way because intis a primitive, it is copied by value. In the first example, "this.bar" would hold a copy of the reference (sort of pointer) to bar. So if you change the original bar (internally), the change will be reflected in your class. Try it.
你的最后一个例子是这样工作的,因为int是一个原语,它是按值复制的。在第一个示例中,“ this.bar”将保存对bar的引用(某种指针)的副本。因此,如果您更改原始栏(在内部),更改将反映在您的班级中。试试看。
回答by aioobe
When a variable is used as argument to a method, it's content is always copied. (Java has onlycall-by-value.) What's important to understand here, is that you can onlyrefer to objects through references. So what actually happens when you pass a variable referring to an object, is that you pass the reference to the object (by value!).
当变量用作方法的参数时,它的内容总是被复制。(Java只有按值调用。)这里要理解的重要一点是,您只能通过引用来引用对象。因此,当您传递引用对象的变量时,实际发生的是您将引用传递给对象(按值!)。
Someone may tell you "primitives are passed by value" and "non primitives are passed by reference", but that is merely because a variable can never contain an object to begin with, only a reference to an object. When this someone understands this, he will agree that even variables referring to objects are passed by value.
有人可能会告诉你“基元是按值传递的”和“非基元是按引用传递的”,但这仅仅是因为变量永远不能包含开始的对象,只能包含对对象的引用。当有人理解这一点时,他会同意即使是引用对象的变量也是按值传递的。
From Is Java "pass-by-reference" or "pass-by-value"?
Java is always pass-by-value. The difficult thing can be to understand that Java passes objects as references passed by value.
Java 总是按值传递。难点在于理解 Java 将对象作为按值传递的引用传递。
From http://www.javaworld.com/javaworld/javaqa/2000-05/03-qa-0526-pass.html
来自http://www.javaworld.com/javaworld/javaqa/2000-05/03-qa-0526-pass.html
Java does manipulate objects by reference, and all object variables are references. However, Java doesn't pass method arguments by reference; it passes them by value.
Java 确实通过引用来操作对象,并且所有对象变量都是引用。但是,Java 不会通过引用传递方法参数;它按值传递它们。
In Java, there is no counter part to the C++ "reference type" for primitives.
在 Java 中,对于基元的 C++“引用类型”没有对应的部分。
回答by Adam
To get that behavior you could modify a member of an object:
要获得该行为,您可以修改对象的成员:
public class Number{
int value;
Number(int value){
this.value = value;
}
public String toString() {
return "" + value;
}
}
You could then do:
然后你可以这样做:
Number x = new Number(7);
Number y = x;
x.value = 9;
System.out.println(y);//prints 9
回答by Bill K
Java never copies objects. It's easiest to think of in terms of for each "new" you will have one object instance--never more.
Java 从不复制对象。最容易想到的是,对于每个“新”,您将拥有一个对象实例——永远不会更多。
People get REALLY CONFUSING when they discuss this in terms of pass by reference/pass by value, if you aren't amazingly familiar with what these terms mean, I suggest you ignore them and just remember that Java never copies objects.
人们在讨论传递引用/传递值时会感到非常困惑,如果您对这些术语的含义并不十分熟悉,我建议您忽略它们并记住 Java 从不复制对象。
So java works exactly the way you wanted your first example to work, and this is a core part of OO Design--the fact that once you've instantiated an object, it's the same object for everyone using it.
因此,java 的工作方式与您希望第一个示例的工作方式完全相同,这是面向对象设计的核心部分——事实上,一旦您实例化了一个对象,对于使用它的每个人来说,它就是同一个对象。
Dealing with primitives and references is a little different--since they aren't objects they are always copied--but the net effect is that java is just about always doing what you want it to do without extra syntax or confusing options.
处理原语和引用有点不同——因为它们不是对象,它们总是被复制——但最终效果是 java 几乎总是做你想要它做的事情,而没有额外的语法或令人困惑的选项。
回答by CoolBeans
In order to keep the original value of member bar, you will need to implement Cloneable interface. Then before assigning a new value to the object, you will need to make a clone of it and pass the cloned value and assign new values to the cloned object. Here is a tutorial on how to do it http://www.java-tips.org/java-se-tips/java.lang/how-to-implement-cloneable-interface.html.
为了保持成员栏的原始值,您需要实现 Cloneable 接口。然后在为对象分配新值之前,您需要对其进行克隆并传递克隆值并将新值分配给克隆对象。这是有关如何操作的教程http://www.java-tips.org/java-se-tips/java.lang/how-to-implement-cloneable-interface.html。

