美文网首页
java方法中的参数传递机制

java方法中的参数传递机制

作者: 西瓜真好吃丶 | 来源:发表于2018-07-27 16:02 被阅读0次

  今天在写排序算法的时候,为了方便以后复习,把每一个排序算法都写在方法里。之前的交换排序、插入排序和选择排序都没有问题,虽然看到方法里接收值有一点疑惑,但还是没有仔细思考过。直到后面写到了归并排序,遇到坑了。

  直接上问题代码:

public class MergeSort {

    public static void main(String[] args) {
        int a[] = {3,1,5,7,2,4,9,6};
        new MergeSort().mergeSort(a);
        for (int i = 0;i < a.length;i++) {
            System.out.print(a[i]+" ");
        }
    }

    public void merge(int [] X, int [] Y, int begin1, int begin2,int n) {
        int i = begin1;
        int j = begin2;
        int k = begin1;
        while (i < begin1 + n && j < begin2 + n && j < X.length) {
            if (X[i] < X[j]) {
                Y[k++] = X[i++];
            }else {
                Y[k++] = X[j++];
            }
        }
        while (i < begin1 + n && i < X.length) {
            Y[k++] = X[i++];
        }
        while (j < begin2 + n && j < X.length) {
            Y[k++] = X[j++];
        }
    }

    public void mergePass(int [] X, int [] Y, int n) {
        for (int i = 0;i < X.length; i = i + 2 * n) {
            merge(X, Y, i, i + n, n);
        }
    }

    public void mergeSort(int [] X) {
        int [] Y = new int[X.length];
        int n = 1;
        while (n < X.length) {
            mergePass(X, Y, n);
            n = n * 2;
            if (n < X.length) {
                mergePass(Y, X, n);
                n *= 2;
            }else {
               /* for (int i = 0;i < X.length;i++) {
                    X[i] = Y[i];
                }*/
               X = Y;
            }
        }
    }
}

最后一步X = Y ,现在看来确实很傻- -。
先简单的解释一下最后一个if-else的作用。
当n即排序子序列长度,小于数组X的长度时,证明数组X还可以再一次合并到数组Y中,于是再做一次合并。
当n >= 数组X的长度时,即表示已合并完。但是如代码中所写的,我的合并是按 把X合并到Y中---->然后再把Y合并到X中---->把X合并到Y中·····这样的顺序进行的。所以会有一种情况导致最后一次合并是把X合并到Y中,这样数组X的值不会改变。于是我就顺手加了一句else {x = y}。把数组Y的引用给数组X。
然而运行的结果不对。


错误.png

仔细看,可以发现这个结果是上一趟的归并排序结果,那么为什么我把排序好的Y给X后,并没有生效呢。
于是我打了两个断点找一找问题的根源。

在运行x = y 之前:

运行前.png
运行前2.png

在这里可以发现对象X 指向的地址和 对象a指向的地址是同一个{int[8]@503}

在运行x = y 之后:


运行后.png
运行后2.png

这样可以看到,当运行X = Y之后,只是把X指向了Y,而数组a并没有任何变化。

由此得出结论:Java 只有值传递参数。当一个对象实例作为一个参数被传递到方法中时,参数的值就是该对象的引用一个副本。指向同一个对象,对象的内容可以在被调用的方法中改变,但对象的引用(不是引用的副本)是永远不会改变的。

  如果参数类型是原始类型,那么传过来的就是这个参数的一个副本,也就是这个原始参数的值,这个跟之前所谈的传值是一样的。如果在函数中改变了副本的值不会改变原始的值。

  如果参数类型是引用类型,那么传过来的就是这个引用参数的副本,这个副本存放的是参数的地址。如果在函数中没有改变这个副本的地址,而是改变了地址中的值,那么在函数内的改变会影响到传入的参数。如果在函数中改变了副本的地址,如new一个,那么副本就指向了一个新的地址,此时传入的参数还是指向原来的地址,所以不会改变参数的值。

于是修改代码:

                for (int i = 0;i < X.length;i++) {
                    X[i] = Y[i];
                }

这样就完成了该归并排序。

相关文章

  • java中方法的参数传递机制

    java中方法的参数传递机制

  • 从0开始复习java(2)

    面向对象 1、方法的参数传递机制 java里方法的参数传递方式只有一种:值传递。 2、方法的所属性 方法不能独立定...

  • java方法中的参数传递机制

      今天在写排序算法的时候,为了方便以后复习,把每一个排序算法都写在方法里。之前的交换排序、插入排序和选择排序都没...

  • Java中的传递是值传递

    Java中的参数类型 形式参数,即形参 实际参数,即实参 Java中的两种参数传递情况 值传递:指在进行函数方法调...

  • Java 参数的传递

    Java 的参数是值传递,不是引用传递 Java 中只有值传递,方法按值调用(call by value)。也就是...

  • Object-c 基础详解

    Object-C 方法传参机制 : OC 中得参数传递都是值传递, 传入参数的是参数的副本; -- 基本类型 (值...

  • Java基础之数组(二)

    一、方法参数的值传递机制 传递的过程是方法被调用时,方法里的参数是以值传递的方式传递的 就是将实际参数的副本传入方...

  • Java 基础笔记

    一、Java中参数传递 Java中方法的参数传递实际上都是值传递,有别于C/C++;在使用对象传递时只能修改对象的...

  • 在上海乐字节学习Java的第十二天

    方法参数的值传递机制main方法的数组参数 参数: 参数类型 String[ ]参数名称:args(argumen...

  • 谈谈Java的方法参数传递机制

    值传递# Java的方法参数传递是值传递!是值传递!值传递!!!重要的事情说三遍。什么是值传递?一个很简单的例子:...

网友评论

      本文标题:java方法中的参数传递机制

      本文链接:https://www.haomeiwen.com/subject/nahgmftx.html