java中的值传递还是引用传递?

java中的值传递还是引用传递?

1. 什么是值传递?

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

    public static void main(String[] args) {
        int a = 1, b = 2;//实参
        System.out.println("a: " + a);
        System.out.println("b : " + b);
        new IntTest().change(a, b);;
        System.out.println("a: " + a);
        System.out.println("b : " + b);
    }
    /**
     * 
     * @author wangbo 2018年2月2日 上午11:55:12
     */
    private void change(int a, int b) {
        a = b;
        System.out.println("change a = b; : " + a);
        b = a +b;
        System.out.println("change b = a +b : " + b);
    }
a: 1
b : 2
change a = b; : 2
change b = a +b : 4
a: 1
b : 2

2. 什么是引用传递?

在C++中,函数参数的传递方式有引用传递。所谓引用传递是指在调用函数时将实际参数的引用(地址)传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数

3. 那么 java 中是值传递还是应用传递?

重要事情说三遍

java所有的参数传递都是传递的副本,变量所代表的值的副本!
java所有的参数传递都是传递的副本,变量所代表的值的副本!
java所有的参数传递都是传递的副本,变量所代表的值的副本!

接下来分别通过 java 基本类型 、 String、 StringBuffer 来进行验证说明


public static void main(String[] args) {
    //定义实参 a、b
    int a = 1, b = 2;
    System.out.println("a : " + a);
    System.out.println("b : " + b);
    //将实参传递到 方法中进行操作
    new IntTest().change(a, b);;
    System.out.println("a : " + a);
    System.out.println("b : " + b);
}
/**
    * 
    * @author wangbo 2018年2月2日 上午11:55:12
    */
private void change(int a, int b) {
    a = b;
    System.out.println("change a = b : " + a);
    b = a +b;
    System.out.println("change b = a +b : " + b);
}

通上面的案例可以得到,java 的基本数据类型,是按值传递的,在方法 change 中,对形参 a、b 进行操作后,对调用者中的实参并未发生影响,调用者中的实参值并未发生改变

在java 中 String ,大家都知道 String 是一个对象,一个不可变的对象,对 String 操作,都会产生一个新的String对象,对原对象不会发生更改,那么在传递中,会是什么样呢??

public static void main(String[] args) {
    String a = "hello ", b = "word";
    System.out.println("a: " + a);
    System.out.println("b : " + b);
    new StringTest().change(a, b);;
    System.out.println("a: " + a);
    System.out.println("b : " + b);
}
/**
    * 
    * @author wangbo 2018年2月2日 上午11:55:12
    */
private void change(String a, String b) {
    a = b;
    System.out.println("change a = b; : " + a);
    b = a +b;
    System.out.println("change b = a +b : " + b);
}

结果:

a: hello 
b : word
change a = b; : word
change b = a +b : wordword
a: hello 
b : word

如上面案例, 在方案 change 的 操作也没有导致 调用者中的实参发生任何改变。

public static void main(String[] args) {
    StringBuffer  a = new StringBuffer("hello"), b = new StringBuffer("word");
    System.out.println("a: " + a);
    System.out.println("b : " + b);
    new StringBuffeTest().change(a, b);;
    System.out.println("a: " + a);
    System.out.println("b : " + b);
}
/**
    * TODO 描述
    * @author wangbo 2018年2月2日 上午11:55:12
    */
private void change(StringBuffer a, StringBuffer b) {
    //这里改变了 a 的值,但上一层 中的a,并未被改变
    a = b;
    System.out.println("change a = b; : " + a);
    //通过 b 引用改变 b 里面的值
    b.append(a);
    System.out.println("change b.append(a) : " + b);
}

结果:

a: hello
b : word
change a = b; : word
change b.append(a) : wordword
a: hello
b : wordword

如上案例,在 change 中对形参a操作,并未导致调用者中的实参发生变化;但对 b 的 “对象的值” 的操作导致了调用者中的实参也发生变化,请注意的是,这里操作的是形参 b 所代表的对象(类 StringBuffer 的实例)里面的值,并不是形参 b 的值;在 java 中对于对象类型变量保存的对象的引用,也就是形参 b 的值 和 实参 b 的值同时指向同一个对象当对形参b进行操作时,并不影响实参 b,但是如果对形参b所指向的对象里面的值进行操作时,会对实参b有影响的。

  Java 语言只有值传递参数。当一个对象实例作为一个参数被传递到方法中时,参数的值就是该“对象的引用”一个副本。实参和形参指向同一个对象,对象的内容可以在被调用的方法中改变,但对象的引用(不是引用的副本)是永远不会改变的。
  在 Java 中永远不会传递对象,而只传递对象引用。因此是按引用传递对象。但重要的是要区分参数是如何传递的,Java 按引用传递对象这一事实并不意味着 Java 应用程序按引用传递参数。参数可以是对象引用,而 Java 是按值传递对象引
用的。
  Java 中的变量可以为以下两种类型之一:引用类型或基本类型。当作为参数传递给一个方法时,处理这两种类型的方式是相同的。 引用类型或基本类型 其实都是传递他们的一份副本,而不是数据本身。在 C++ 中当传递给函数的参数是引用时,您传递的就是这个引用,或者内存地址(按引用传递)。在 Java 中传递给方法的一个引用类型参数时,您传递的是该引用的一个副本(按值传递),而不是引用本身。
  由于 java 中 引用类型保存值一个对象的引用,在传递中形参虽然实参的一个副本,但两者指向同一个对象,当对形参中的对象的值进行操作时,实参也会发生改变

猜你喜欢

转载自blog.csdn.net/wbxx727124/article/details/79238598