我一直以为Java使用pass-by-reference. 但是,我读了一篇博客文章,声称Java使用pass-by-value. 我不认为我明白作者所做的区别。
什么是解释?
我一直以为Java使用pass-by-reference. 但是,我读了一篇博客文章,声称Java使用pass-by-value. 我不认为我明白作者所做的区别。
什么是解释?
当前回答
Java,当然,毫无疑问,是“通过价值”。 此外,由于Java是(主要)对象导向和对象与参考工作,它很容易被困惑,并认为它是“通过参考”
但要测试它是否真的通过值或通过参考,你可以使用原始类型和参考:
@Test
public void sampleTest(){
int i = 5;
incrementBy100(i);
System.out.println("passed ==> "+ i);
Integer j = new Integer(5);
incrementBy100(j);
System.out.println("passed ==> "+ j);
}
/**
* @param i
*/
private void incrementBy100(int i) {
i += 100;
System.out.println("incremented = "+ i);
}
产量是:
incremented = 105
passed ==> 5
incremented = 105
passed ==> 5
因此,在两种情况下,任何在方法中发生的事情都不会改变真正的对象,因为对象的价值已经过去了,而不是对象本身的参考。
但是,当你将自定义对象转移到一种方法,而一种方法并改变它时,它也会改变真正的对象,因为即使你通过了对象,你也将其参考作为一种价值转移到一种方法。
@Test
public void sampleTest2(){
Person person = new Person(24, "John");
System.out.println(person);
alterPerson(person);
System.out.println(person);
}
/**
* @param person
*/
private void alterPerson(Person person) {
person.setAge(45);
Person altered = person;
altered.setName("Tom");
}
private static class Person{
private int age;
private String name;
public Person(int age, String name) {
this.age=age;
this.name =name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("Person [age=");
builder.append(age);
builder.append(", name=");
builder.append(name);
builder.append("]");
return builder.toString();
}
}
在这种情况下,产量是:
Person [age=24, name=John]
Person [age=45, name=Tom]
其他回答
我会以另一种方式说:
在 Java 引用中,这些引用是通过的(但不是对象),这些引用是通过的值(引用本身是复制的,你有 2 引用作为结果,你没有控制在方法中的第 1 引用下)。
例如,在Python相同的情况,但有文章,描述他们称之为Pass-by-reference,只有原因引用被使用。
Pass By Reference 收到的函数值是通话者所使用的对象的参考。 通话者所指的对象的任何函数都将被通话者看到,并将从那时起与这些变化进行操作。
正如这些定义所表明的那样,参考通过值是毫无意义的,如果我们要接受这个定义,那么这些术语就变得毫无意义,所有语言都只是通过值。
因此,有了这个理解,我们可以看看Java,并看到它实际上有两种。所有Java原始类型总是通过值,因为你收到一个复印件的呼叫器的对象,并且不能修改他们的复印件。
Java 是由價值通過的。
在某种程度上,我从来没有透露过原始数据类型和对象的值/参考。因此,我用下列代码来测试我的满意度和清晰度;可能有助于寻求类似清晰度的人:
class Test {
public static void main (String[] args) throws java.lang.Exception
{
// Primitive type
System.out.println("Primitve:");
int a = 5;
primitiveFunc(a);
System.out.println("Three: " + a); //5
//Object
System.out.println("Object:");
DummyObject dummyObject = new DummyObject();
System.out.println("One: " + dummyObject.getObj()); //555
objectFunc(dummyObject);
System.out.println("Four: " + dummyObject.getObj()); //666 (555 if line in method uncommented.)
}
private static void primitiveFunc(int b) {
System.out.println("One: " + b); //5
b = 10;
System.out.println("Two:" + b); //10
}
private static void objectFunc(DummyObject b) {
System.out.println("Two: " + b.getObj()); //555
//b = new DummyObject();
b.setObj(666);
System.out.println("Three:" + b.getObj()); //666
}
}
class DummyObject {
private int obj = 555;
public int getObj() { return obj; }
public void setObj(int num) { obj = num; }
}
如果行 b = 新 DummyObject() 没有评论,随后进行的修改是在一个新的对象,一个新的实例上进行的。 因此,它不反映在方法被召回的地方。 但是,否则,变化是反映的,因为修改只是在对象的“参考”上进行的,即 - b 点到相同的 dummyObject。
在这个条纹中的答案之一(https://stackoverflow.com/a/12429953/4233180)的描述可以帮助获得更深入的理解。
Bob 保持他的列表,他称之为 tinyHouseAt1234Main,与相机相机,允许他在实时注意到实际房子的任何变化。
这个奇怪的副作用,通过一个列表到新的自动化服务是混乱的人谁问它是如何工作的。 事实上,什么是区别的能力远程控制机器人,改变的状态的房子在1234 Main, vs. 实际上物理上去那里,因为安妮给了你地址?
当涉及到对象时,对象本身不能转移到方法,所以我们通过对象的参考(地址)我们可以使用这个参考来操纵原始对象。
Account account1 = new Account();
此分類上一篇
如果我们将 array1 参考变量的值转换为反向Array 方法的论点,则在该方法中创建一个参考变量,而该参考变量则开始指向相同的序列(a)。
public class Test
{
public static void reverseArray(int[] array1)
{
// ...
}
public static void main(String[] args)
{
int[] array1 = { 1, 10, -7 };
int[] array2 = { 5, -190, 0 };
reverseArray(array1);
}
}
此分類上一篇
所以,如果我们说
array1[0] = 5;
我们有另一个参考变量在逆Array 方法(array2) 指向一个 array c. 如果我们要说
array1 = array2;
如果我们返回参考变量序列2作为逆序列方法的返回值,并将此值归咎于参考变量序列1在主要方法,序列1在主要将开始指向序列c。
public class Test
{
public static int[] reverseArray(int[] array1)
{
int[] array2 = { -7, 0, -1 };
array1[0] = 5; // array a becomes 5, 10, -7
array1 = array2; /* array1 of reverseArray starts
pointing to c instead of a (not shown in image below) */
return array2;
}
public static void main(String[] args)
{
int[] array1 = { 1, 10, -7 };
int[] array2 = { 5, -190, 0 };
array1 = reverseArray(array1); /* array1 of
main starts pointing to c instead of a */
}
}
此分類上一篇