我一直以为Java使用pass-by-reference. 但是,我读了一篇博客文章,声称Java使用pass-by-value. 我不认为我明白作者所做的区别。
什么是解释?
我一直以为Java使用pass-by-reference. 但是,我读了一篇博客文章,声称Java使用pass-by-value. 我不认为我明白作者所做的区别。
什么是解释?
当前回答
Java 编程语言仅通过值的论点,也就是说,您无法从所称方法中更改呼叫方法中的论点值。
但是,当一个对象例子作为论点转移到一种方法时,论点的价值不是对象本身,而是对象的参考。
对于许多人来说,这似乎是通过参考,行为上,它与通过参考有很多共同点,但是,有两个原因,这是不准确的。
第一,改变已转化为一种方法的能力仅适用于对象,而不是原始价值;第二,与对象类型变量相关的实际价值是对象的参考,而不是对象本身。
The following code example illustrates this point:
1 public class PassTest {
2
3 // Methods to change the current values
4 public static void changeInt(int value) {
5 value = 55;
6 }
7 public static void changeObjectRef(MyDate ref) {
8 ref = new MyDate(1, 1, 2000);
9 }
10 public static void changeObjectAttr(MyDate ref) {
11 ref.setDay(4);
12 }
13
14 public static void main(String args[]) {
15 MyDate date;
16 int val;
17
18 // Assign the int
19 val = 11;
20 // Try to change it
21 changeInt(val);
22 // What is the current value?
23 System.out.println("Int value is: " + val);
24
25 // Assign the date
26 date = new MyDate(22, 7, 1964);
27 // Try to change it
28 changeObjectRef(date);
29 // What is the current value?
30 System.out.println("MyDate: " + date);
31
32 // Now change the day attribute
33 // through the object reference
34 changeObjectAttr(date);
35 // What is the current value?
36 System.out.println("MyDate: " + date);
37 }
38 }
This code outputs the following:
java PassTest
Int value is: 11
MyDate: 22-7-1964
MyDate: 4-7-1964
The MyDate object is not changed by the changeObjectRef method;
however, the changeObjectAttr method changes the day attribute of the
MyDate object.
其他回答
public void foo(Object param)
{
// some code in foo...
}
public void bar()
{
Object obj = new Object();
foo(obj);
}
它是相同的......
public void bar()
{
Object obj = new Object();
Object param = obj;
// some code in foo...
}
不要考虑在这个讨论中不相关的站点。
你会遇到的最常见的运营商之一是简单的任务运营商“="......它将其右上的值归分为其左上的运营商: int cadence = 0; int speed = 0; int gear = 1; 这个运营商也可以用于对象归分对象参考。
很明显,这个运营商如何以两种不同的方式行动:分配值和分配参考;最后,当它是一个对象......第一,当它不是一个对象,即当它是一个原始的。
真相在代码中,让我们尝试一下:
public class AssignmentEvaluation
{
static public class MyInteger
{
public int value = 0;
}
static public void main(String[] args)
{
System.out.println("Assignment operator evaluation using two MyInteger objects named height and width\n");
MyInteger height = new MyInteger();
MyInteger width = new MyInteger();
System.out.println("[1] Assign distinct integers to height and width values");
height.value = 9;
width.value = 1;
System.out.println("-> height is " + height.value + " and width is " + width.value + ", we are different things! \n");
System.out.println("[2] Assign to height's value the width's value");
height.value = width.value;
System.out.println("-> height is " + height.value + " and width is " + width.value + ", are we the same thing now? \n");
System.out.println("[3] Assign to height's value an integer other than width's value");
height.value = 9;
System.out.println("-> height is " + height.value + " and width is " + width.value + ", we are different things yet! \n");
System.out.println("[4] Assign to height the width object");
height = width;
System.out.println("-> height is " + height.value + " and width is " + width.value + ", are we the same thing now? \n");
System.out.println("[5] Assign to height's value an integer other than width's value");
height.value = 9;
System.out.println("-> height is " + height.value + " and width is " + width.value + ", we are the same thing now! \n");
System.out.println("[6] Assign to height a new MyInteger and an integer other than width's value");
height = new MyInteger();
height.value = 1;
System.out.println("-> height is " + height.value + " and width is " + width.value + ", we are different things again! \n");
}
}
这就是我跑步的结果:
Assignment operator evaluation using two MyInteger objects named height and width [1] Assign distinct integers to height and width values -> height is 9 and width is 1, we are different things! [2] Assign to height's value the width's value -> height is 1 and width is 1, are we the same thing now? [3] Assign to height's value an integer other than width's value -> height is 9 and width is 1, we are different things yet! [4] Assign to height the width object -> height is 1 and width is 1, are we the same thing now? [5] Assign to height's value an integer other than width's value -> height is 9 and width is 9, we are the same thing now! [6] Assign to height a new MyInteger and an integer other than width's value -> height is 1 and width is 9, we are different things again!
我们不能那么确定,因为在 [6] 对象是相同的,然后我们将一个新的对象归分给其中一个,然后,对象有不同的价值! 他们现在如何区分,如果他们是相同的? 他们应该在这里也是相同的!!!
此操作员也可以用于对象分配对象参考。
当涉及到对象时,对象本身不能转移到方法,所以我们通过对象的参考(地址)我们可以使用这个参考来操纵原始对象。
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 */
}
}
此分類上一篇
Java 以参考方式操纵对象,而所有对象变量都是参考。
例如,使用 badSwap() 方法:
public void badSwap(int var1, int
var2{ int temp = var1; var1 = var2; var2 =
temp; }
public void tricky(Point arg1, Point arg2)
{ arg1.x = 100; arg1.y = 100; Point temp = arg1; arg1 = arg2; arg2 = temp; }
public static void main(String [] args) {
Point pnt1 = new Point(0,0); Point pnt2
= new Point(0,0); System.out.println("X:
" + pnt1.x + " Y: " +pnt1.y);
System.out.println("X: " + pnt2.x + " Y:
" +pnt2.y); System.out.println(" ");
tricky(pnt1,pnt2);
System.out.println("X: " + pnt1.x + " Y:" + pnt1.y);
System.out.println("X: " + pnt2.x + " Y: " +pnt2.y); }
如果我们执行这个主要()方法,我们会看到以下输出:
X: 0 Y: 0 X: 0 Y: 0 X: 100 Y: 100 X: 0 Y: 0
该方法成功地改变了 ofpnt1 的值,尽管它通过了值;但是,pnt1 和 pnt2 的交换失败了! 这是混乱的主要来源. 在 themain() 方法中,pnt1 和 pnt2 只是对象参考。 当你 passpnt1 和 pnt2 到 tricky() 方法时,Java 通过了值的参考,就像其他参数一样。
Java 复制并通过参考值,而不是对象. 因此,方法操纵将改变对象,因为参考指向原始对象. 但因为参考是复制,交换将失败. 如图 2 描述,方法参考交换,但不是原始参考。
我试图简化上面的例子,只保持问题的本质. 让我把这个作为一个容易记住和正确应用的故事。 故事如下: 你有一个宠物狗,吉米,尾巴长12英寸。
下次你旅行,你带狗,无意中,到一个邪恶的<unk>子,他也是长尾的仇恨者,所以他把它切到一个可怜的2英寸,但他这样做你的亲爱的吉米,而不是一个克隆。
public class Doggie {
public static void main(String...args) {
System.out.println("At the owner's home:");
Dog d = new Dog(12);
d.wag();
goodVet(d);
System.out.println("With the owner again:)");
d.wag();
badVet(d);
System.out.println("With the owner again(:");
d.wag();
}
public static void goodVet (Dog dog) {
System.out.println("At the good vet:");
dog.wag();
dog = new Dog(12); // create a clone
dog.cutTail(6); // cut the clone's tail
dog.wag();
}
public static void badVet (Dog dog) {
System.out.println("At the bad vet:");
dog.wag();
dog.cutTail(2); // cut the original dog's tail
dog.wag();
}
}
class Dog {
int tailLength;
public Dog(int originalLength) {
this.tailLength = originalLength;
}
public void cutTail (int newLength) {
this.tailLength = newLength;
}
public void wag() {
System.out.println("Wagging my " +tailLength +" inch tail");
}
}
Output:
At the owner's home:
Wagging my 12 inch tail
At the good vet:
Wagging my 12 inch tail
Wagging my 6 inch tail
With the owner again:)
Wagging my 12 inch tail
At the bad vet:
Wagging my 12 inch tail
Wagging my 2 inch tail
With the owner again(:
Wagging my 2 inch tail
我认为这个简单的解释可以帮助你理解,因为我想在我正在争论这一点时理解这一点。
当您将原始数据传输到函数呼叫时,其内容将复制到函数的论点,当您传输一个对象时,其参考将复制到函数的论点。
考虑到这个简单的例子,线条是Java的对象,当你改变一个线条的内容时,参考变量现在将指向一些新的参考,因为线条对象在Java中是不可变的。
String name="Mehrose"; // name referencing to 100
ChangeContenet(String name){
name="Michael"; // refernce has changed to 1001
}
System.out.print(name); //displays Mehrose
很简单,因为正如我提到的那样,您不允许在呼叫函数中更改复制的参考,但问题在于当您通过 String/Object 序列时,该序列。
String names[]={"Mehrose","Michael"};
changeContent(String[] names){
names[0]="Rose";
names[1]="Janet"
}
System.out.println(Arrays.toString(names)); //displays [Rose,Janet]
你不能这样做
Student student1= new Student("Mehrose");
changeContent(Student Obj){
obj= new Student("Michael") //invalid
obj.setName("Michael") //valid
}