我一直以为Java使用pass-by-reference. 但是,我读了一篇博客文章,声称Java使用pass-by-value. 我不认为我明白作者所做的区别。
什么是解释?
我一直以为Java使用pass-by-reference. 但是,我读了一篇博客文章,声称Java使用pass-by-value. 我不认为我明白作者所做的区别。
什么是解释?
当前回答
假设,常见的语言是错误的,基于不准确的语言
编程语言的作者没有权力重新命名已建立的编程概念。
原始 Java 类型 byte, char, short, int, long float, double 肯定是通过值。
所有其他类型都是对象:对象成员和参数技术上是参考。
因此,这些“参考”是通过的“值”,但没有对象建设发生在架子上. 任何对象成员的变化(或对象在序列的情况下)适用于相同的原始对象;这种参考正是符合一个例子的指标的逻辑转移到某个函数在任何C直径,在那里我们使用称之为通过一个对象的参考。
特別我們有這件事 java.lang.NullPointer 例外,這在純粹的過值概念中毫無意義。
其他回答
Java 严格要求 pass-by-value. 通过使用 pass-by-values 的参数不会影响/改变原始变量. 在下一个程序中,我们启动了一种称为 'x' 的变量,并使用 pass-by-value 技术来证明变量的值如何保持不变。
public class Main
{
public static void main(String[] args)
{
//Original value of 'x' will remain unchanged
// in case of call-by-value
int x = 5;
System.out.println( "Value of x before call-by-value: " + x);
// 5
processData(x);
System.out.println("Value of x after call-by-value: " + x);
// 5
}
public static void processData(int x)
{
x=x+10;
}
}
通过值和通过参考值之间的差异
什么是 Pass by Value?
通过值,函数参数的值将复制到记忆中的另一个位置,在函数内访问或修改变量时,它只会访问复制。
通过参考,记忆地址转移到该函数,换句话说,函数可以访问实际变量。
定义
Pass by value 是指将函数参数值复制到另一个变量的机制,而 pass by reference 是指将实际参数转移到函数的机制。
变化
目前的参数
Java 总是通过价值,没有例外,永远。
因此,怎样才能让任何人完全困惑,相信Java是通过参考,或者认为他们有一个Java作为通过参考的例子?关键点是Java从来没有提供直接访问对象本身的价值,在任何情况下。
因此,当呼叫一种方法时
对于原始论点(int、long等)而言,值的过渡是原始的实际价值(例如,3)。
所以,如果你有DoSomething(foo)和公共空白DoSomething(Foo foo) {.. } 两个 Foos 有复制的参考,指向相同的对象。
当然,通过值对一个对象的参考看起来非常相似(并且在实践中不可分辨的)通过对象的参考。
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 描述,方法参考交换,但不是原始参考。
首先,我们应该明白什么是通过值或通过参考的意思。
通过值:方法参数值复制到另一个变量,然后复制的对象通过,这就是为什么它被称为通过值。
public class Balloon {
private String color;
public Balloon(){}
public Balloon(String c){
this.color=c;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
}
public class Test {
public static void main(String[] args) {
Balloon red = new Balloon("Red"); //memory reference 50
Balloon blue = new Balloon("Blue"); //memory reference 100
swap(red, blue);
System.out.println("red color="+red.getColor());
System.out.println("blue color="+blue.getColor());
foo(blue);
System.out.println("blue color="+blue.getColor());
}
private static void foo(Balloon balloon) { //baloon=100
balloon.setColor("Red"); //baloon=100
balloon = new Balloon("Green"); //baloon=200
balloon.setColor("Blue"); //baloon = 200
}
//Generic swap method
public static void swap(Object o1, Object o2){
Object temp = o1;
o1=o2;
o2=temp;
}
}
当我们执行上述程序时,我们会跟踪输出。
red color=Red
blue color=Blue
blue color=Red
Balloon red = new Balloon("Red");
Balloon blue = new Balloon("Blue");
public static void swap(Object o1, Object o2){ //o1=50, o2=100
Object temp = o1; //temp=50, o1=50, o2=100
o1=o2; //temp=50, o1=100, o2=100
o2=temp; //temp=50, o1=100, o2=50
} //method terminated
如果你已经明白了这一点,你可以轻松地理解混乱的原因. 因为变量只是对物体的参考,我们会感到困惑,我们正在通过参考,所以Java通过参考。
现在,让我们分析 foo() 方法执行。
private static void foo(Balloon balloon) { //baloon=100
balloon.setColor("Red"); //baloon=100
balloon = new Balloon("Green"); //baloon=200
balloon.setColor("Blue"); //baloon = 200
}
第一行是最重要的,当我们称之为一个方法时,该方法在参考位置上被称为对象,在这一点上,气球指向100,因此它的颜色变成红色。
Java 总是通过值,而不是通过参考。
Pass by reference(也称为 pass by address)是指实际参数地址的副本存储。
public class PassByValue {
public static void main(String[] args) {
Test t = new Test();
t.name = "initialvalue";
new PassByValue().changeValue(t);
System.out.println(t.name);
}
public void changeValue(Test f) {
f.name = "changevalue";
}
}
class Test {
String name;
}
让我们一步一步了解一下:
Test t = new Test();
正如我们都知道,它将创建一个对象,并将参考值返回t 例如,假设t 的值为 0x100234 (我们不知道实际的 JVM 内部值,这只是一个例子) 。
此分類上一篇
new PassByValue().changeValue(t);
通过 t 函数时,它不会直接通过对象测试的实际参考值,但它会创建 t 的副本,然后将其转移到函数。 因为它通过值,它会通过变量的副本而不是实际的参考值。 因为我们说 t 的值是 0x100234, t 和 f 都将具有相同的值,因此它们将指向相同的 ob。
此分類上一篇
public class PassByValue {
public static void main(String[] args) {
Test t = new Test();
t.name = "initialvalue";
new PassByValue().changeRefence(t);
System.out.println(t.name);
}
public void changeRefence(Test f) {
f = null;
}
}
class Test {
String name;
}
这会扔一个NullPointerException吗? 不,因为它只通过一个副本的参考。 在通过参考的情况下,它可能会扔一个NullPointerException,如下所示:
此分類上一篇
希望这能帮助。