Java中的值传递和引用传递

数据类型

首先了解一下Java中的数据类型
数据类型:

  • 基本类型
  • 对象类型

对应的,变量类型:

  • 基本类型
    包括byte,short,int,long,char,float,double,boolean...
  • 引用类型
    包括 类、接口和数组

基本类型和引用类型的区别

  • 存值
    基本类型的变量保存原始值,即它代表的值就是数值本身
    引用类型的变量保存引用值,指向内存空间的地址,对象本身存放在这个地址的位置
  • 空间分配
    基本类型是在声明时就分配空间
    引用类型在声明时只分配引用空间,不分配数据空间
    "引用"也是占用空间的,一个空Object对象的引用大小大概是4byte

值传递和引用传递

进入主题

概念

值传递:方法调用时,实参把它的值直接传递给形参,函数接收到的是原始值的copy,此时内存中存在两个相等的基本类型,即实参和形参,后面方法都是对这个形参的修改,不影响实参
引用传递:方法调用时,实参把它的引用传给形参,函数接收到的是原始值的内存地址,此时实参和形参指向同一片内存地址,对形参的修改会影响到实参

举一个栗子:

class MyObj{
    public int b=99;
}
 public static void main(String[] args) { 
        ReferencePkValue2 t = new ReferencePkValue2(); 
        int a=99; 
        t.test1(a);//这里传递的参数a就是按值传递 
        System.out.println(a); //此处是对实参的输出 99
         
        MyObj obj=new MyObj(); 
        t.test2(obj);//这里传递的参数obj就是引用传递
        System.out.println(obj.b); //此处是对实参的输出 100 
    } 
     
    public void test1(int a){ 
        a++;
        System.out.println(a);  //此处是对形参的输出 100 
        } 
     
    public void test2(MyObj obj){ 
        obj.b=100;
        System.out.println(obj.b); //此处是对形参的输出 100 
        }

输出:
100;
99;
100;
100;
由结果可见,只有在值传递时实参没有受到影响

这里要特殊考虑String,以及IntegerDouble等几个基本类型包装类,它们都是immutable类型,
因为没有提供自身修改的函数,每次操作都是新生成一个对象,所以要特殊对待,可以认为是和基本数据类型相似,传值操作

再看一个栗子:

public static void main(String[] args){
        ReferencePkValue1 pk=new ReferencePkValue1();
        //String类似基本类型,值传递,不会改变实际参数的值
        String test1="Hello";
        pk.change(test1);
        System.out.println(test1); //输出为 Hello
         
        //StringBuffer和StringBuilder等是引用传递
        StringBuffer test2=new StringBuffer("Hello");
        pk.change(test2);
         
        System.out.println(test2.toString()); //输出为 Helloworld
    }
     
    public void change(String str){
        str=str+"world";
    }
     
    public void change(StringBuffer str){
        str.append("world");
    }

总结

  • 基本数据类型传值,对形参的修改不会影响实参
  • 引用类型传引用,形参和实参指向同一个内存地址(同一个对象),所以对参数的修改会影响到实际的对象
  • String, Integer, Doubleimmutable的类型特殊处理,可以理解为传值,最后的操作不会修改实参对象

你可能感兴趣的:(Java中的值传递和引用传递)