关于Java的以下陈述是假的吗?
在Java中,当一个类或对象的实例被指定为方法的参数时,正在创建该对象的副本
我知道Java中的函数是按值传递的,这意味着正在制作对象的副本吗?
但与此同时,如果java对象是引用并且你传递了一个引用,这与实际数据的副本不同吗?
如果你传递一个引用,当重新分配引用时,对象将被重新分配,使得Java传递引用不是按值传递的?
正如您所看到的,我非常对此感到困惑
答案 0 :(得分:7)
在java中,所有内容都是通过副本传递的。
原始文件通过副本传递。因此,在函数内部更改它不会反映在外部。
对象 传递给函数的内容是引用的副本(不是对象的副本)。这意味着更改函数内部的属性外部引用会看到修改,但更改引用本身(例如,赋值为null)不会反映在函数外部。
按照一些例子来解释一下。
更改基元的功能:
public void notChange(int a) {
a = 3;
// Here a is 3
}
int a = 0;
notChange(a);
// Here a is 0
用于更改对象内部内容的函数
public void changeContent(List<String> list) {
list.add("x");
// Here list has one more element
}
List<String> list = new ArrayList<String>();
// Here list has size 0
changeContent(list);
// Here list has size 1
对于更改对象引用的函数
public void changeReference(List<String> list) {
list = null;
}
List<String> list = new ArrayList<String>();
changeReference(list);
// Here list is not null
答案 1 :(得分:0)
如果是对象,则传递参考的副本。请注意,此 并不意味着传递了对象本身的副本 。您对该对象所做的任何更改也将反映在原始对象中。如果你没有正确复制你的对象,这可能会导致一些疯狂的事情。使用复制构造函数或类似的东西来复制对象。
答案 2 :(得分:0)
这是一个按值传递并在c ++中通过引用传递的示例。在此示例中,java的行为类似于按值传递版本。该值是指向对象的指针。
#include <stdio.h>
class Obj{
int value;
public:
Obj(int v){
value = v;
}
void echo(){
printf("%d\n", value);
}
};
void byValue(Obj* obj){
obj = new Obj(-1);
obj->echo();
}
void byReference(Obj*& obj){
obj = new Obj(-1);
obj->echo();
}
int main(int argc, char** args){
Obj* o = new Obj(1);
byValue(o);
o->echo();
byReference(o);
o->echo();
return 0;
}
(抱歉泄漏,这不是良好做法的一个例子) 输出是:
-1
1
-1
-1
答案 3 :(得分:0)
我会尝试从第一个问题开始逐步回答你:
在Java中,当一个类或对象的实例被指定为 方法的参数,正在制作该对象的副本
这是 false ,当您将对象传递给方法时,Java永远不会复制它,因为 Davide Lorenzo 表示您正在传递对象的引用,不是对象本身所以如果方法修改了类的某些属性,你将在方法之外修改值。
所以我们可以回答第二和第三个问题:
我知道Java中的函数是按值传递的,这意味着 正在制作一个对象的副本?
不,Java不会复制。正如 Davide Lorenzo 所说,你传递的是参考文献的副本而不是对象的副本。
但与此同时,如果java对象是引用而你传递了一个 参考,这是不同的实际数据的副本不是吗?
是的,传递引用与传递对象的副本完全不同。 我将通过一个例子澄清一切。 假设我们的对象 Flower 的属性为 color
public class Flower{
String color = "red";
}
enter code here
我们可以想象 AnotherObject 的方法 setColor
public void setColor(Flower flower, String color_string){
flower.color = color_string;
}
我们可以有以下情况
public static void main(String args[]){
Flower myFlower = new Flower();
AnotherObject otherObject = new AnotherObject();
otherObject.setColor(myFlower, "yellow");
System.out.println("The color of the flower is: "+myFlower.color);
}
此代码的输出将为:
The color of the flower is yellow
这就是你传递对象引用的原因,而不是对象本身。
现在你可以问为什么Java被认为是按值传递? 有关此问题的this previous post有一个非常有趣的讨论,我想引用它的最佳答案:
Java始终是按值传递的。不幸的是,他们决定打电话 指针引用,从而混淆了新手。因为那些参考 按值传递。
最后但并非最不重要的是请注意,只有原始类型不会通过Java中的引用进行管理,因此传递 int 与传递 Integer 完全不同,我建议你看一下关于这个论点的this post。
答案 4 :(得分:0)
在Java中,当一个类或对象的实例被指定为 方法的参数
这是你出错的地方。每个参数都有一个类型。 Java中唯一的类型是基本类型和引用类型。因此,Java中参数(或任何其他变量或任何表达式的值)的值只能是基元或引用。不是“对象”。