哪有什么引用传递,所有都是值传递

哪有什么引用传递,所有都是值传递

经常看到有人说什么值传递、引用传递,其实都是值传递,区别不过是传的值的类型罢了。

传值方式

java传值有且只有一种方式,将参数的“值”复制后传入,这个“值”是指变量名所对应的地址中存放的值,对于值类型和对象类型,由于地址中存放的东西不同,因此表现有所不同:

  • 对于8种值类型,其存放的就是本身的值,因此表现为将值传递到函数中,修改后的值对原值无影响。
  • 对于对象来说,其存放的是对象头,里面包含了对象的类型、首地址等。将对象头的值传递到函数中,其仍然能正确指向对象本身。

传递的是值的拷贝,而非其本身

值类型

对于值类型来说

7++;

这种无疑是错误的,因为不能对常量进行修改。任何一个IDE都会报错。
image
但如果将其作为参数传入

public class ObjTest {
    public static void main(String[] args) {
        inc(7);
    }

    private static void inc(int a) {
		a++;
		System.out.println(a);
	}
}

那么就不会报错,并且输出8。这是因为在传递到函数里面的并不是常量7,而是一个拷贝int a = 7,而a是一个int类型的变量,因此可以自增。

对象

而对于对象来说,同样如此。

public class ObjTest {
    public static void main(String[] args) {
        inc(7);
        Node n1 = new Node();
        f1(n1);
        System.out.println("n1 = " + n1);
    }

    private static void f1(Node node) {
        node.a++;
        node.b += 2;
        node.c += 3;
        node.d = new int[]{1, 5};
        // 在此设置断点2
        node = new Node();
        node.a = -1;
        node.b = -2;
        node.d[0] = 3;
        System.out.println("node = " + node);
    }

    private static void inc(int a) {
        a++;
        System.out.println(a);
    }

}

public class Node {
    public int a;
    public int b;
    public int c;
    public int[] d = new int[2];
}

在执行到断点1的时候,如下图所示,可以看到,n1的所有值都为默认值,地址为0x704
image

在执行到断点2(此行未执行)时,如下图所示,可以看到,node指向的地址仍为@704,值已经进行了对应的修改
image

继续执行到函数结束,可以看到node指向了@708,属性的值变为了新的值。
image

结束子函数,回到主函数中,可以看到n1的所有属性都与node指向@704时相同
image

可见,同值类型的变量相同,传入子函数的对象头node并不是主函数中的对象头n1本身,而是它的一个拷贝,他们指向同一个对象@704,无论是通过n1,还是初始的node,都可以对@704进行操作(调用方法,修改属性),因而好像和值类型的传递有所不同。但如果修改node本身的值,令其指向@708,这对n1没有任何影响,n1依然指向@704。此后通过node修改对象的值,修改的是@708的值,与@704没有任何关系,因此也对主函数中的n1没有任何影响。
因此,所谓引用传递,不过是值是引用(或者说指针)的值传递。

hmoban主题是根据ripro二开的主题,极致后台体验,无插件,集成会员系统
自学咖网 » 哪有什么引用传递,所有都是值传递