Java 的参数传递方式

Photo by Joey Kyber on Unsplash

Photo by Joey Kyber on Unsplash

Java 的方法(method)有两个特点:

  1. 方法不能独立存在,必须依赖类和对象
  2. 方法不能被独立执行,只能以“类.方法”或“对象.方法”的方式执行
  3. 方法若没有 static 关键字的修饰,则方法属于类的实例

简单一点理解:如果说“骑单车”是一种方法,那么脱离了人或熊,没有了对象的“骑单车”也就没有意义,也不可以单独执行,因为力的作用是相互的,没有施力物体,单车不可能自己动,总不可能是一个鬼在“骑单车”吧==!。

Java 里方法的传递方式只有一种:值传递,就是将实际参数(实参)的副本传入到方法中,而实际参数的本身不会受到影响。实际参数是在 main 方法中定义的初始变量,如

1
2
3
4
5
6
public static void main(String[] args)
{
// a, b 均为实际参数
int a = 6;
int b = 9;
}

在 Java 中基本类型的参数传递比较好理解,有点难理解的是引用类型的参数传递。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class DataWrap
{
// 定义两个成员变量 a 和 b
int a;
int b;
}
public class ReferenceTransferTest
{
public static void swap(DataWrap dw)
{
// swap 方法实现 a 和 b 的值交换
int tmp = dw.a;
dw.a = dw.b;
dw.b = tmp;
System.out.println("swap 方法里,a 成员变量的值是" + dw.a + ";b 成员
变量的值是" + dw.b);
}
public static void main(String[] args)
{
// 新建 DataWrap 对象 dw
DataWrap dw = new DataWrap;
// 赋值
dw.a = 6;
dw.b = 9;
// 调用 swap 方法
swap(dw);
System.out.println("交换结束后,a 成员变量的值是" + dw.a + ";b 成员
变量的值是" + dw.b);
}
}
程序执行结果

程序执行结果

如何理解 Java 的引用参数传递机制?

首先,新建 DataWrap 对象 dw 并赋值,这时 main 方法和 swap 方法同时对堆内存中的 dw 对象有一个指针,即它们两个方法实际引用的是同一个内存区域;然后,main 方法中调用 swap 方法,完成值的交换,这时 dw 所在的内存区域 ab 的值已经完成交换;最后,交换结束之后,dw.a 等于 9dw.b 等于 6。需要注意的是,在调用 swap 方法时,传入到 swap 的并不是 dw 对象本身,而仅仅是它的副本。

main 方法和 swap 方法指向同一个对象

main 方法和 swap 方法指向同一个对象

形参个数可变的方法

当调用方法的时候,可以传入多个字符串作为参数值,在 Java 中有两种传入多个参数的方法。

1
2
3
4
\\形参个数可变方式
public static void method(int price, String... brand);
\\数组形式
public static void method(int price, String[] brand);

两种方式分别调用的方式为:

1
2
method(100, "BMW", "QQ", "BYD");
method(100, new String[]{"BMW", "QQ", "BYD"});

从上面两种调用方式来看,第一种更加简洁易懂,推荐使用第一种。

在 Java 中,允许同一个类中定义多个同名方法,区分它们的地方在于形参列表不同就行了,这种被称为方法重载

static 关键字

static 关键字修饰的成员属于类本身,而不属于该类的实例。所以,用实例去调用 static 修饰的成员变量和方法是不行的,会出现“无法从静态上下文中引用非静态方法…”的错误。解决此问题的办法是重新建立一个对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class CallPhone
{
public void call()
{
System.out.println("正在打电话...");
}
public static void main(String[] args)
{
//新建对象访问非静态方法
CallPhone p = new CallPhone();
p.call();
// this.call();
// System.out.println("正在打电话给X...");
}
}

CallPhone p = new CallPhone(); 这行代码中创建了一个实例也就是对象,实际上生成了两个东西:一个是变量 p,一个是对象 CallPhone,其中变量存储在栈内存中,对象存储在堆内存中,对象与变量之间通过引用的方式建立联系。

觉得还不错?帮我赞助点域名费吧:)