Java方法参数传递问题

版权声明:欢迎评论和转载,转载时请注明作者和出处,共同维护良好的版权和知识产权秩序。 https://blog.csdn.net/CrazyOnes/article/details/82666655

前言

参数传递的问题从C语言开始就一直追随我们,最近本人在最准备校招面试,发现他还是如蛆附骨,如影随形。所以我们有必要和他一决高下了。

参数传递在我学习C语言的时候知道了两种,一种是传值,一种是传地址(其实仔细思考都是在传递值,只不过传地址是传递指针的值)。如果想通过函数改变参数本身,就需要传地址才能修改。后来学习了C++,知道C++为了减少指针的操作,使用引用来达到相同的效果。

这样就有了两种参数调用方法,一种是按值调用,一种是按引用调用,当然我在书上还看到了一种,那就是按名调用(古老的高级语言Algol曾经使用这种方法,但是在今天这种传递方式已经成为了过去式了)


Java方法参数传递

上边说了三种调用方法,但是一定要记住,Java只有一种调用方式,就是按值调用。

然后我们针对传递基本类型和非基本类型来进行讨论:

基本类型调用:

这个其实大家都不陌生,如果传递基本类型的话,方法得到的值将是基本类型的拷贝,那么无论执行什么样的操作都不会对原始值造成影响。

因为原始值和拷贝后的值不在一块内存区域中,所以各自执行操作都不会对对方的值造成影响。

非基本类型调用:

非基本类型也是按值调用,可能有些同学会有疑问,因为不是说好的传递非基本类型可以对他的内容进行修改吗?那不就是按引用传递吗?比如在下边的程序中:

public class Employee {
    int a = 3;

    public static void main(String[] args) {
    	Employee x = new Employee();
    	
    	System.out.println(x.a);
    	tripleA(x);
    	System.out.println(x.a);
    }
    
    public static void tripleA(Employee e) {
    	e.a = e.a * 3;
    }
}

输出结果为:

3
9

但是实际上他的内部操作是这样的:

首先 Employee x = new Employee(); 程序申请一块内存空间存储 Employee 对象,然后令x指向它。

然后调用tripleA() 将x传递给函数,此时e是x的一份拷贝,也就是引用的拷贝,这时他们两个都指向相同的Employee对象,所以当函数改变e.a的值的时候,才可以真正改变x.a的值。

可以结合图示查看分析这个过程:

所以此时函数才可以改变x.a的值。


知识进阶

讲了这么多学没学会实践一下最重要(答案在解析后边,做完之后再看答案哦)

例题:
检查程序,是否存在问题,如果存在指出问题所在,如果不存在,说明输出结果。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

package algorithms.com.guan.javajicu; 

public class Example { 

  String str = new String("good"); 

  char[] ch = {'a','b','c'}; 

  public static void main(String[] args) { 

     Example ex = new Example(); 

     ex.change(ex.str, ex.ch); 

     System.out.print(ex.str +"and"); 

     System.out.print(ex.ch);  

  

    

  public void change(String str, char ch[]){ 

     str= "test ok"

     ch[0]= 'g'

  

A.test okandabc

B.test okandgbc

C.goodandabc

D.goodandgbc

解析:

在调用change方法之前,我们的内存里的关系是这样的:

然后我们调用change方法,传入参数之后,在未执行change方法内的任何语句之前,内存里的关系是:

这一步也就是我们前边讲的,参数传递之后会将引用拷贝一份作为方法内的局部变量,此时他们两两指向相同的对象。

现在需要知道的是当使用""双引号为String类型赋值的过程类似于任意类 new Object()的过程,也就是重新让这个变量指向了一个新的对象(当然new String() 和 直接使用双引号赋值还是有区别的,而且也不简单,但是不是我们研究的重点,所以不去讨论,只是做一个简化)。而ch修改了指向对象的第一个元素,所以接下来,内存中的关系就会发生微妙的变化。

说到这里,我想大家基本上也知道结果是什么了,change方法中的str指向了新的对象,并没有影响到main方法中str实际指向的对象,change方法中的ch改变了指向对象中的内容,影响到了main方法中ch指向的对象,所以输出结果就是goodandgbc.

正确答案:D

如果能将这个过程全部理解,那么基本上在参数传递上就入门不少啦,上边的例题是网易的一道招聘笔试题。


如有错误,欢迎指摘。

猜你喜欢

转载自blog.csdn.net/CrazyOnes/article/details/82666655