为什么java中只有值传递

值传递||引用传递??

值传递(pass by value):是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果参数进行修改,将不会影响到实际参数

引用传递(pass by reference):是指在调用函数的时候将实际参数的地址直接传递到函数中,那么在函数中对参数的修改,将影响到实际参数。

区别:值传递会创建副本,引用传递不会

到底是什么传递?

关于java中的参数传递是值传递还是引用传递的问题,对于我这个新手来说的确是十分恼火的,之前我的不确定理解(...反正不清楚)是如果传递的参数是普通类型,那就是值传递,如果是对象,那就是引用传递。而在我看到Hollis的关于这个问题的讲解时,我豁然开朗,原来java中只有值传递呀。

为什么会存在参数是对象类型的时候是引用传递的理解呢?因为有代码证明呀~~~(事实是举例不当)

例子 1

public class Test{
public static void main(String[] args){
 Test test=new Test();
    Elployee elployee=new Employee();
    elployee.setName("elployee-A");
    elployee.pass(elployee);
    System.out.println("print in main,user is "+elployee);
}
    public void pass(Employee elployee){
    elployee.setName("elployee-B")
    System.out.println("print in pass,user is "+elployee);
    }
}

输出结果如下:

print in pass,user is {name='elployee-B'}

print in main,user is {name='elployee-B'}

经过pass方法后,实参的值竟然被改变了,那么按照上面的引用传递的定义,这不就是引用传递了么,所以有人就得出了在java的方法中,传递的是对象类型的时候是引用传递。

但是,这种表述事实上是错误,我们接着看下面一个同样是对象作为参数的情况

例子 2

public class Test{
public static void main(String[] args){
 Test test=new Test();
    Elployee elployee=new Employee();
    elployee.setName("elployee-A");
    elployee.pass(elployee);
    System.out.println("print in main,user is "+elployee);
}
    public void pass(Employee elployee){
    elployee=new Employee();
    elployee.setName("elployee-B")
    System.out.println("print in pass,user is "+elployee);
    }
}

输出结果:

print in pass,user is {name='elployee-B'}

print in main,user is {name='elployee-A'}

在上面的pass中改变了elployee对象,如果是引用传递的话那么在输出应该跟例子1一样呀,但是并不一样,这是为什么呢?

事实上在上面的过程中,当我们调用pass方法的时候,并把elployee作为实际参数传递给形式参数elployee的时候,会把实际参数的地址给形式参数,这时形式参数也指向了实际参数的地址。所以在例子1中,我们对形式参数的属性进行修改的时候会影响到实际参数,因为此时形式参数持有的地址就是直接参数的地址。而在例子2中,形式参数得到实际参数的地址后,我们又对形式参数重新分配一个对象实例,此时形式参数不在只有实际参数的地址,而是持有新建立的对象的地址。

也就是说,这里实际是把实际参数的地址复制了一份,传递给了形式参数。所以这个过程其实是值传递,把实际对象的地址当做了值传递给了形式参数。

更加详细的内容:https://mp.weixin.qq.com/s/F7Niaa7nD1tLApCEGKAj4A

原来是值传递呀!

在了解到Java中只有值传递后,脑海中又浮现出好像看到过相关知识的情节。于是再去翻 java核心技术卷I的时候,发现在关于方法参数的那一节讲过这个问题,其中给出了如下例子。

public static void swap(Employee x,Employee y){
    Employee temp=x;
    x=y;
    y=temp;
}
public static void main(String[] args){
Elployee a=new Employee("Alice",...);
Elployee b=new Employee("Bob",...);
swap(a,b);
}

执行swap(a,b)后,a仍然是Alice 而 b仍然是Bob。

由此也可以看出参数传递的方式为值传递。

# JAVA 

标题:为什么java中只有值传递
作者:amore
地址:HTTPS://iamwaiting.cn/articles/2019/10/28/1572216852597.html
彧语:乾坤未定,你我皆是黑马!!!

评论

  1. 先给出一个名词,求值策略。首先明确不管是值传递还是引用传递都是一种求值策略,越过了求值策略而去谈具体的求值方式,我觉得意义不大。求值策略是计算机科学上的一个概念,wiki是这样说的, 求值策略是确定编程语言中表达式的求值的一组(通常确定性的)规则。在了解求值策略是什么后,再谈编程语言中有没有值传递,值传递到底是什么?我觉得比较合理一些。另,任何编程语言都只是使用变量去指向内存地址,这句话我只可以理解到,在编程语言中,是怎么通过一个变量名得到变量的具体的值。我并不能看出这跟值传递有什么关系。又怎么说明了值传递不存在。关于最后一句“值传递”的概念只不过是指向了同一个内存地址,我觉得这是没有理解到值传递的本质,才会这样去理解。值传递与引用传递的本质区别在于有没有拷贝,这跟指向是否同一个内存地址并无关系。

  2. 我一直觉得“值传递”这个说法从根本上就是不正确的,任何编程语言都只是使用变量去指向内存地址,根本没有什么“值传递”。现在普遍被接受的“值传递”的概念只不过是指向了同一个内存地址。

  3. ??撒呢

  4. 没有值传递了?不太清楚你具体说的什么例子。

  5. 当你使用一个符号、字母、数字的组合去储存某一个值的时候,就没有值传递了,所有的变量都是对值的引用

  6. String str = "abc";
    str.replace("b","d");
    System.out.println(str);
    
    

取消