Java中的按值传递还是按引用传递?
我读了很多文章,都说Java是按价值传递的。但我仍然没有解释传递值和引用之间的区别。我编写了一个示例程序,它的执行方式如下Java中的按值传递还是按引用传递?,java,Java,我读了很多文章,都说Java是按价值传递的。但我仍然没有解释传递值和引用之间的区别。我编写了一个示例程序,它的执行方式如下 public class PassByValue { private int a; private int b; public PassByValue(int a, int b) { this.a = a; this.b = b; } public static int mul(int a, int b) {
public class PassByValue {
private int a;
private int b;
public PassByValue(int a, int b) {
this.a = a;
this.b = b;
}
public static int mul(int a, int b) {
int z = a * b;
System.out.println("The Value of Z inside mul: " + z);
return z;
}
public static void main(String args[]) {
int z = 100;
int x = 40;
int y = 20;
mul(x,y);
PassByValue pass = new PassByValue(x,y);
mul(pass.a,pass.b);
System.out.println("The Value of Z" + z);
}
}
执行
800
800 and
100
谁能给我解释一下这些问题
混淆可能是因为变量首先不能包含对象。变量只能包含对对象的引用。(换句话说,对象根本不通过引用或值传递。) 一旦意识到这一点,很明显Java中没有任何东西是通过引用传递的。引用对象的变量存储引用,该引用通过值传递
1。什么是传递值意味着… 答:它只是将存储在变量中的数字或值传递给函数。我是对还是错 对。传递的是变量中包含的值,而不是变量本身 1。如何说Java是按值传递的? Java是按值传递的,因为原语是按值传递的,而引用是按值传递的。(永远不会传递对象。) 例如,您不能在Java中实现
swap
方法。也就是说,你做不到
String str1 = "hello";
String str2 = "world";
swap(str1, str2);
// str1 can't refer to anything but "hello"
// str2 can't refer to anything but "world"
2。为什么Java是按值传递而不是按引用传递的?
如上所述,即使引用也是按值传递的。您可以将按值传递视为只传递变量中包含的值,而不传递变量本身。然后将该值复制到另一个临时变量中。相比之下,您可以将“按引用传递”视为传递实际变量,并且不进行临时复制,因此变量中的任何更改都会被“保存”。虽然还有更多的问题,但思考问题可能更容易些。你的答案是对的,但你缺乏细节。如果你这样做
Dog d=新狗()
d
是对Dog实例的引用,即pass by value的意思是当您将d
传递到一个方法中时
walkDog(d)代码>
将引用的副本(即引用的值,而不是引用本身)传递到Dog中。因此,您有两个对Dog实例的引用,一个在调用范围内,另一个在被调用范围内。假设在walkDog
方法中有一行
d=新狗()代码>
方法中的d
引用仅指向新狗。最初调用该方法的原始引用仍然指向原始
狗。如果Java有pass-by-reference,那么方法中将使用相同的引用,而不是引用的副本,因此更改引用的值将影响调用和被调用范围中的引用
编辑——根据你们的评论,我想把事情弄清楚。由于原始范围和方法范围中的引用都指向同一个对象,因此您仍然可以在两个范围中更改该对象上的内容。所以如果你这样做了
d.drinkWater()代码>
在walkDog
方法中,和drinkWater
更改dog对象上的一些变量,因为两个引用都指向同一个对象,该对象已更改
这只是每个范围中引用的实际内容之间的区别。但是它确实出现了很多问题。我认为,如果Java支持按引用传递或值传递,那么应该清楚如何在实现中使用Java中的类实例。所有这些都是实例的类型——可变/不可变,这将决定我们将东西传递给函数的方式!这取决于你去探索这种差异
让我澄清一下我的论点,为什么没有必要追根究底地通过什么?!考虑这个…
第一个代码:
void foobar(int *a){
printf("%d", *a);
}
int main(){
int a = 5;
foobar(&a);
return 0;
}
在这段C代码中,您要传递什么。。。变量“a”的地址。这恰好是通过引用传递的!:)
让我们考虑另一个…
第二个代码:
void foobar(int* a){
printf("%d", *a);
}
int main(){
int a = 5;
int *p = &a;
foobar(p);
return 0;
}
在这个C代码中,我要传递什么。。。。?变量“p”的值与它是指针还是什么无关:p
那么,您将其称为“按值传递/按引用传递”是什么呢?我把这个留给你!但我们需要考虑的是如何实施……:)
所以在Java中。。。通过我们传递的东西,我们可以说,它支持“按值传递”或“按引用传递某个实例”,而不是“按引用传递”
***我唯一能清楚得出结论的是Java中的原始数据类型。因为没有指针可以在没有实际变量的情况下编辑字节的内容,所以在Java中我们不能对它们(我指的是原始数据类型)进行按引用传递。我们需要多少次这个问题?看看任何一个“相关”链接,有一个很好的机会阅读其中两个实际已回答但未关闭的链接,因为重复的链接会清除问题。hvgotcodes的可能重复:谢谢。。。完美的解释。。。如果我错了,请纠正我,我没有发送原始变量或对函数的引用。。。而是一份副本。。。因此,该值仅在该范围内发生变化,而不是在每个位置……因此,复制引用和原始引用指向相同的地址位置。。。。但是对于DOG的不同实例。@theJava,没有两个引用指向同一个DOG。更改其中一个引用不会更改另一个引用,而是使用对ch的任一引用