Java中的值传递和引用传递

2021/10/2 17:09:59

本文主要是介绍Java中的值传递和引用传递,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

值传递和引用传递

注:java中是值传递。

那么在进行赋值修改的过程中,引用类型的内部值也发生了改变? 这又是怎么回事?

参考链接: https://blog.csdn.net/pcwl1206/article/details/86550268

  • 当传递方法参数类型为基本数据类型(数字以及布尔值)时,一个方法是不可能修改一个基本数据类型的参数
  • 当传递方法参数类型为引用数据类型时,一个方法将修改一个引用数据类型的参数所指向对象的值。
  • 即使 Java 函数在传递引用数据类型时,也只是拷贝了引用的值罢了,之所以能修改引用数据是因为它们同时指向了一个对象,但这仍然是按值调用而不是引用调用。

Java是值传递

  • 当传的是基本类型时,传的是值的拷贝,对拷贝变量的修改不影响原变量;
  • 当传的是引用类型时,传的是引用地址的拷贝,但是拷贝的地址和真实地址指向的都是同一个真实数据,因此可以修改原变量中的值;
  • 当传的是String类型时,虽然拷贝的也是引用地址,指向的是同一个数据,但是String的值不能被修改,因此无法修改原变量中的值。

自己的代码例子:

  • 基本数据类型:
package com.AL.base;

/**
 * 值传递和引用传递。  java中是值传递.  pass by value,  pass by reference
 * java内存中存储的东西内容: 堆:new的对象和数组, 栈:基本数据类型和引用类型
 * 基本数据类型:值就直接保存在这个变量中;  引用类型:保存的地址值  是指向对象内容的地址,实际对象的地址【引用指向实际对象,实际对象中存放着内容】
 *
 * 如果参数是基本类型,传递的是基本类型的字面量值的拷贝。【当传的是基本类型时,传的是值的拷贝,对拷贝变量的修改不影响原变量】
 * 如果参数是引用类型,传递的是该参量所引用的对象在堆中地址值的拷贝。
 */
public class passByValue_BaseDataType {
    public static void main(String[] args) {
        int a = 10;
        System.out.println("change方法调用前");
        System.out.println("a:->" + a);
        change(a);
        System.out.println("change方法调用后");
        System.out.println("a:->" + a);
    }
    public static void  change(int a){
        a = a + 10;
        System.out.println("change方法中");
        System.out.println("a :" + a);
    }
}

结果:

change方法调用前
a:->10
change方法中
a :20
change方法调用后
a:->10
  • 引用类型: 对于String 类型(final修饰,不可变)[其实 Integer类型也是]
package com.AL.base;

/**值传递和引用传递
 * 对于 String 类型,引用类型。 在进行值改变的时候, 究竟是什么?
 * 当传的是引用类型的时候,传递的是引用地址的拷贝,即拷贝地址和真实地址指向的是同一个对象,所以会改变原变量中的值。
 */
public class passByValue_String {
    public static void main(String[] args) {
        String str1 = new String("abc");
        String str2 = "abcde";
        System.out.println("change方法调用前");
        System.out.println("str1 :" + str1);
        System.out.println("str2 :" + str2);
        change(str1);
        change(str2);
        System.out.println("change方法调用后");
        System.out.println("str1 :" + str1);
        System.out.println("str2 :" + str2);
    }
    public static void change(String str){
       // str = str + "!!!!!!";
        str = "alzn";
        System.out.println("change方法中");
        System.out.println("str :" + str);
    }
    /**
     运行的结果为:
     change方法调用前
     str1 :abc
     str2 :abcde
     change方法中
     str :alzn
     change方法中
     str :alzn
     change方法调用后
     str1 :abc
     str2 :abcde

     分析原因: 拿 str1 = "abc"举例
     String是引用类型,栈中存放的变量是指向堆中 "abc" String类型的 地址值,这个地址指向堆中具体的值。
     那么在调用change方法时,它会拷贝变量,拷贝的值是 引用地址,并不会拷贝堆中的数据。 所以,在传递引用类型时 会改变原变量中的值。
     为什么这里 String没有改变呢???
     栈中 0x10 指向 堆中"abc" String; 在调用时,会进行引用地址的拷贝 假设 0x11 中存放。 0x10和0x11两者均指向 abc,
     在进行改变数据的时候,由于String的不可变性质, 则0x11会另外指向一个 alzn 在堆中的引用地址,不会改变原有的"abc"数据
     */
}
  • 引用类型:StringBuffer,长度可变的字符串类型
	package com.AL.base;

/**
 * 值传递和引用传递:
 * 关于StringBuffer的特性:StringBuffer是长度可变的,线程安全,在对元素进行操作的时候,会有 synchronized 修饰进行同步
 * StringBuild 长度可变,但线程不安全
 */
public class passByValue_StringBuffer {
    public static void main(String[] args) {
        StringBuffer str1 = new StringBuffer("abc");
        StringBuffer str2 = new StringBuffer();
        str2.append("abcdef");
        System.out.println("change方法调用前");
        System.out.println("str1 :" + str1);
        System.out.println("str2 :" + str2);
        change(str1);
        change(str2);
        System.out.println("change方法调用后");
        System.out.println("str1 :" + str1);
        System.out.println("str2 :" + str2);
    }
    public static void change(StringBuffer str){
        // str = str + "!!!!!!";
        str.append("alzn");
        System.out.println("change方法中");
        System.out.println("str :" + str);
    }
}

结果为:

change方法调用前
str1 :abc
str2 :abcdef
change方法中
str :abcalzn
change方法中
str :abcdefalzn
change方法调用后
str1 :abcalzn
str2 :abcdefalzn


这篇关于Java中的值传递和引用传递的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程