当我通过参数将对象传递给方法时,对象是通过值传递还是引用传递?问题来自这段代码:
int a = 2;
cambiar(a);
System.out.println(a);
public static void cambiar(int c) {
c = 10;
}
在上面的代码中,我已经知道我不会以a
任何方式修改 a ,除非该方法返回一个 int 并保存它。但是在下面的代码中会发生什么?
class otraCualquiera {
Partidas partidas = new Partidas();
Ventana ventana = new Ventana();
Gestor gestor = new Gestor(ventana,partidas);
}
class culquiera {
private Ventana view;
private Partidas play;
public Gestor(Ventana v, Partidas p) {
view = v;
play = p;
}
}
主要问题,为什么我可以直接从任何人的班级修改其他班级?( view.setTitle("View sería un jframe")
) 并且从我展示的第一个代码中我无法修改int
?
在任何事情之前...
在 Java 中,没有通过引用传递这样的东西。按值传递(或某些人称之为复制)是强制性的。
你会说,但是当我通过参数传递一个数组并从传递它的方法修改它时,它会改变,我没有传递数组的副本
看来我的论点失败了,但我会解释一下:
您存储在非原始变量中的不是对象本身,而是对象在动态内存空间中的地址或标识符。当您将变量作为参数传递时,您传递的是该地址的副本。
您提出的案例
您已经创建了三个类型
Partidas
为Ventana
和的对象Gestor
。对象
Gestor
在其属性中存储对象的地址Partidas
以及Ventana
作为参数传递给它们的内容。尚未创建传递对象的副本。您所拥有的是对象地址的副本。如果您在已经拥有的之后将以下行添加到 Manager 构造函数中:
您只需使参数
v
不再存储类型对象的地址Ventana
。在类otraCualquiera
中,变量ventana
仍将具有正确的地址。因此,总是通过值的副本传递,不像在 C 或 C++ 中允许通过引用传递。您必须了解的是,在对象的情况下,变量存储的值是对象的地址或标识符,而不是对象本身。
如果您想要找到一种方法来修改原始类型变量(如 int)从您传递给的另一个方法(这不是很常见,但在某些递归算法中很有用),一种技术可能是要将整数作为单元素数组,那么它将被视为一个对象,并且您只会传递其地址的副本(完整的引用)。
通常的想法是将它存储为一个对象
Integer
,但是这个类是不可变的。这里要记住的要点是在 Java 中:
第二点是引起很多混乱的一点。在Java中,当我们遇到以下情况时:
...我们通常说变量的值是一个“对象”,但这种说法是一种日常的简化——一种方便的不精确。如果我们想深入了解这个问题,我们必须了解 Java 的工作方式,其值
saludos
不是对象,而是对对象的引用。变量、引用和对象是三个相关但独立的事物,您必须仔细查看哪些操作影响哪些操作以及以何种方式影响。例如:saludos = "¡Saludos de nuevo!";
)改变了变量的值。但是在这种情况下变量的值是一个引用,而不是一个对象。赋值不访问对象——它严格使用变量及其值。a == b
ora != b
,看变量的当前值。当这些值是引用时,它们会查看这些引用但不会访问它们的对象。null
它是一个参考,而不是一个对象。根据定义,它是没有对象的引用。saludo.length()
)或成员引用(objeto.variable
)观察变量的当前值,并访问与该引用对应的对象。您给出的所有示例都可以通过严格应用这些规则来回答。例如:
在这个例子中,与你所说的相反,没有直接修改另一个类。你实际上在做的是:
view
;setTitle
这个对象的方法,传递给它一个对对象的引用"View sería un jframe"
。这本身并没有改变任何东西。如果有修改,那是间接的,因为该方法
setTitle
直接修改了某些东西,或者通过调用其他方法间接导致了这种修改。如果您再次查看我的列表,项目 #1 是唯一实际修改变量值的机制。其他任何一点都没有直接修改任何东西的“权力”。尽管说
view.setTitle("View sería un jframe")
“修改view
”是一种流行且简化的描述发生情况的方式,但实际上,当我们严格观察事情的运作方式时,情况并非如此。Java 中没有引用。参数通过复制传递(语言的基本类型变量或通过复制存储它们的地址)这不是通过引用传递!!!!!!!。通过引用传递是创建具有不同名称但引用相同内存空间的变量或对象的别名。例如:
内存空间 10 -> 我们将 person1 对象存储在这个空间中。引用将是 -> 创建一个 personReference 对象,它是 person1 的别名。
总之,引用就像以各种方式调用内存空间而不使用额外的内存资源。
在 Java 中使用副本。变量的内容,或者在对象的情况下,它所在的内存地址。在这两种情况下,变量的内容都被复制到另一个变量或一个对象的内存地址到另一个对象(它在 C 中称为指针),不同之处在于 Java 以专用方式处理它,而不是在 C 中它确实程序员直接。