Java函数参数调用中的陷阱

更新时间 🔔🕙 2023年2月5日

环境:JDK7

在java中,一般认为函数调用是两种方式(传值,传引用)。
基本类型(int,short,String等)采用传值,
类类型(Integer,Long,自定义类等)采用传址。
实际上,java所有的参数均采用传值方式:
基本类型(int,short,String等)将值复制一遍,然后传递给函数,
类类型(Integer,Long,自定义类等)将引用地址复制一遍,然后传递给函数。

1.测试用java代码如下:
package test;

public class A {
public int name;

public A(int name) {
this.name = name;
}

public static void main(String[] argv) {
A a1 = new A(111);
A a2 = new A(222);

System.out.println("swapRef");
System.out.println("before swap a1=" + a1.name);
System.out.println("before swap a2=" + a2.name);
swapRef(a1, a2);
System.out.println("after swap a1=" + a1.name);
System.out.println("after swap a2=" + a2.name);
System.out.println();

System.out.println("swapContent");
System.out.println("before swap a1=" + a1.name);
System.out.println("before swap a2=" + a2.name);
swapContent(a1, a2);
System.out.println("after swap a1=" + a1.name);
System.out.println("after swap a2=" + a2.name);
}

// 函数内交换参数的引用
public static void swapRef(A ia, A ib) {
A temp = ia;
ia = ib;
ib = temp;
}

// 函数内交换参数的内容
public static void swapContent(A ia, A ib) {
int temp = ia.name;
ia.name = ib.name;
ib.name = temp;
}
}

运行的结果是:

swapRef
before swap a1=111
before swap a2=222
after swap a1=111
after swap a2=222

swapContent
before swap a1=111
before swap a2=222
after swap a1=222
after swap a2=111
2.类似于C++中的下列代码:
#pragma once
class A
{
public:
A(void);
~A(void);
int name;
};
#include "StdAfx.h"
#include "A.h"

A::A(void)
: name(0)
{
}

A::~A(void)
{
}
#include "stdafx.h"
#include <iostream>
#include "A.h"
void swapRef(A* a, A* b) {
A* swapTemp = a;
a = b;
b = swapTemp;
}
void swapContent(A* a, A* b) {
int swapTemp = a->name;
a->name = b->name;
b->name = swapTemp;
}
int _tmain(int argc, _TCHAR* argv[])
{
A a1;
a1.name = 111;
A a2;
a2.name = 222;
std::cout<<"swapRef"<</iostream>

运行的结果是:

swapRef
before swap a1=111
before swap a2=222
after swap a1=111
after swap a2=222

swapContent
before swap a1=111
before swap a2=222
after swap a1=222
after swap a2=111
3.由此,就可以理解,为什么下列代码没有改变参数内容了。
// 函数内部生成参数对象
public static void change(A ia, A ib) {
ia = new A(555);
ib = new A(666);
}
转载请备注引用地址:编程记忆 » Java函数参数调用中的陷阱