JAVA中的方法

前言

李刚老师《JAVA疯狂讲义》第5版,第5章学习笔记。

1.JAVA方法的所属性

JAVA中,方法是对类或对象行为特征的抽象,它是类或对象的最重要的组成部分。面向对象编程中的方法,结构化编程中的函数,二者到底有什么本质区别呢?

二者所属性不同,结构化编程中,函数可被单独执行,函数不属于任何事物,软件由一个个函数构成,函数是程序的老大。面向对象的编程中,方法不可被单独执行,方法属于类或对象,软件由一个个类构成,类是程序的老大,方法是类的跟班。

在JAVA中,如果要定义一个方法,只能在类中定义,如果方法被static修饰,则该方法属于这个类,如果方法没有static修饰,则方法属于类的对象。JAVA语言是静态的, 一旦类的定义完成后,只要不重新编译,则该类和类的对象所拥有的方法都是固定的,永远不会改变。

2.JAVA方法的参数传递机制

声明方法时的参数叫做形参,调用方法时传递给形参的参数值叫做实参,那么在内存中,实参的值是如何传递给形参的呢?
JAVA中的参数传递方式只有值传递一种,也就是说,将实参的值复制一份,传给形参,但是,实参本身不会受到影响,例如:

	public static class PrimitiveTransferTest{
		public static void swap(int a , int b) {
			//定义一个交换变量值的方法
			int tem = a;
			a = b;
			b = tem;
			System.out.println("swap方法中,a的值为:" + a + ",b的值为:" + b);
		}
	}
	public static void main(String args[]) {
		PrimitiveTransferTest p = new PrimitiveTransferTest();
		int a = 3;
		int b = 5;
		p.swap(a, b);
		System.out.println("调用swap方法后,a的值为:" + a + ",b的值为:" + b);
	}

代码运行结果为:
swap方法中,a的值为:5,b的值为:3
调用swap方法后,a的值为:3,b的值为:5

说明swap()方法中,a,b值的改变,没有影响main()方法中,a,b值的改变,具体原因如下:

JAVA程序执行入口为main()方法,当开始执行main()方法,在main()方法中定义a、b两个int型变量时,内存形式如下:
JAVA方法参数传递方法1

随后,借助类的对象调用swap()方法后,JAVA内部会开辟一个swap()方法的内存空间,其中的变量值从main()方法栈内存中拷贝而来,具体如下:
JAVA方法参数传递方法2
可见,虽然变量名相同,但是main()方法中的两个变量和swap中的两个变量是不同的,保存在内存中的不同区域。在swap()方法执行完毕后,内存中结果如下:

JAVA方法参数传递方法3
可见,改变的只是swap()方法栈内存中的变量,而main()方法中的变量并未改变,这就是JAVA方法的参数传递机制,不会改变main()方法中本来的变量!

无论是基本类型的参数传递,还是引用类型的参数传递,例如:

	public static class PrimitiveTransferTest{
		public static void swap(DataWrap dw) {
			//定义一个交换变量值的方法,方法的形参为引用变量
			int tem = dw.a;
			dw.a = dw.b;
			dw.b = tem;
			System.out.println("swap方法中,a的值为:" + dw.a + ",b的值为:" + dw.b);
		}
	}
	public static void main(String args[]) {
		PrimitiveTransferTest p = new PrimitiveTransferTest();
		DataWrap dw = new DataWrap();
		dw.a = 3;
		dw.b = 5;
		p.swap(dw);
		System.out.println("调用swap方法后,a的值为:" + dw.a + ",b的值为:" + dw.b);
	}

这段程序的运行结果是:
swap方法中,a的值为:5,b的值为:3
调用swap方法后,a的值为:5,b的值为:3

看起来,似乎形参和实参的值都发生了变化,和形参为基础类型时的机制不同,其实并非这样。具体如下:

当main()方法中创建了DataWrap这个类的对象dw,并对dw的两个成员变量a,b赋值后,内存中为:
JAVA方法形参为引用变量时的参数传递机制1
调用swap方法后,main()方法中的dw变量的值会赋值到swap()栈内存中,由于main()栈内存中dw储存的为对象的地址,因此swap()栈内存中,也是对象的地址,在传递参数后,内存中为:

JAVA方法形参为引用变量时的参数传递机制2
swap()方法中,将实参的值赋值过来,同样也指向了堆内存中的同一个对象,在swap()方法执行完毕后,内存中结果如下:
JAVA方法形参为引用变量时的参数传递机制3
所以,方法的参数传递机制并没有变化,main()栈内存中的dw变量并未发生任何变化,指向的还是堆内存中的对象,但是swap()方法执行后,对象本身发生了变化,导致看起来,实参dw也发生了变化。

3.JAVA方法的递归

JAVA的方法中,可以调用其自身,这就是方法的递归,这是一种隐形的循环,而无需循环控制语句。例如:
已知一个数列:
f(0) = 1
f(1) = 4
f(n+2) = 2*f(n+1) + f(n),n >= 0
求f(10),递归的写法为:

	public static class Recursive{
		public static int fn(int n) {
			if(n == 0) {
				return 1;
			}
			else if (n == 1) {
				return 4;
			}
			else {
				return 2*fn(n-2)+fn(n-1);
			}
		}
	}
	public static void main(String args[]) {
		Recursive r = new Recursive();
		System.out.println(r.fn(10));
	}

注意,一定要保证递归最终在某个时刻的返回值的确定的,比如上述例子中,可以保证递归最终回到n=1或者n=0,不然就会导致无限递归,死循环。也就是说,递归一定要向已知的方向递归。

4.JAVA方法的重载

JAVA允许在一个类中定义多个同名的方法,只要形参列表不同就OK,这就是方法的重载,可见,JAVA中唯一确定一个方法需要三个因素:

  1. 所属的类或对象
  2. 方法名
  3. 形参列表
    举例如下:
	public static class overLoad{
		public void test() {
			System.out.println("方法重载测试1");
		}
		public void test(String msg) {
			System.out.println("方法重载测试2"+msg);
		}
	}

上述代码中实现了test()方法的重载,虽然方法名相同,但是二者形参列表不同,因此系统可以正常的区分这两个方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值