我一直以为Java使用pass-by-reference. 但是,我读了一篇博客文章,声称Java使用pass-by-value. 我不认为我明白作者所做的区别。
什么是解释?
我一直以为Java使用pass-by-reference. 但是,我读了一篇博客文章,声称Java使用pass-by-value. 我不认为我明白作者所做的区别。
什么是解释?
当前回答
它是原始值或参考值的副本,如果是原始值,它是价值的比特的副本,如果是对象,它是参考值的副本。
public class PassByCopy{
public static void changeName(Dog d){
d.name = "Fido";
}
public static void main(String[] args){
Dog d = new Dog("Maxx");
System.out.println("name= "+ d.name);
changeName(d);
System.out.println("name= "+ d.name);
}
}
class Dog{
public String name;
public Dog(String s){
this.name = s;
}
}
使用 Java PassByCopy:
名称= Maxx 名称= Fido
原始粘贴类和线条是不可变的,因此使用这些类型的任何例子都不会像其他类型/对象一样工作。
其他回答
主要的角石知识必须是引用的一个,
当对象引用转移到一种方法时,引用本身通过使用呼叫值。 但是,因为引用的值是指对象,则该值的副本仍然是指其相应论点所引用的相同对象。
Java: A Beginner's Guide 第六版 希尔伯特·希尔德
例如,使用 badSwap() 方法:
public void badSwap(int var1, int var2)
{
int temp = var1;
var1 = var2;
var2 = temp;
}
当 badSwap() 返回时,作为论点过渡的变量将仍然保持其原始值。 该方法也会失败,如果我们将论点类型从 int 转换为 对象,因为 Java 通过对象参考值也。
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
图1 转移到一个方法后,对象将至少有两种参考。
Java 复制并通过参考值,而不是对象. 因此,方法操作将改变对象,因为参考指向原始对象. 但是,因为参考是复制,交换将失败。 方法参考交换,但不是原始参考。 不幸的是,在一个方法呼叫后,你只剩下未交换的原始参考。
在这里,每一个单一的答案都倾向于从其他语言中提到通过指标,并显示在Java中不可能做什么,因为任何原因,没有人试图从其他语言中展示如何实施通过对象的价值。
这个代码表明如何做这样的事情:
public class Test
{
private static void needValue(SomeObject so) throws CloneNotSupportedException
{
SomeObject internalObject = so.clone();
so=null;
// now we can edit internalObject safely.
internalObject.set(999);
}
public static void main(String[] args)
{
SomeObject o = new SomeObject(5);
System.out.println(o);
try
{
needValue(o);
}
catch(CloneNotSupportedException e)
{
System.out.println("Apparently we cannot clone this");
}
System.out.println(o);
}
}
public class SomeObject implements Cloneable
{
private int val;
public SomeObject(int val)
{
this.val = val;
}
public void set(int val)
{
this.val = val;
}
public SomeObject clone()
{
return new SomeObject(val);
}
public String toString()
{
return Integer.toString(val);
}
}
在这里,我们有一个函数需要值,它正在立即创建一个对象的克隆,需要在对象本身的类中实施,而该类必须被标记为克隆。
可能很好,Java没有通过参考语法,但称之为“通过价值”的语言沿着有愿望的思维线。
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 中的所有对象参考都通过值. 这意味着将值的副本转移到一个方法. 但技巧是通过值的副本也会改变对象的实际值。
请参见下面的例子,
public class ObjectReferenceExample {
public static void main(String... doYourBest) {
Student student = new Student();
transformIntoHomer(student);
System.out.println(student.name);
}
static void transformIntoDuleepa(Student student) {
student.name = "Duleepa";
}
}
class Student {
String name;
}
在此情况下,它将是Duleepa! 原因是Java对象变量只是指在记忆中真正的对象的参考。 因此,即使Java通过值的参数到方法,如果变量点到对象的参考,实际对象也会被更改。