Java中再谈方法

一. 方法的重载
Java中允许出现同一个类中定义多个同名的方法,只要形参列表不同就行。如果同一个类中包含了两个或者两个以上方法的方法名相同,但形参列表不同,则被称位方法重载。

class OverLoad{
public void sum (){
}
static  int sum (int i ,int j){
return i*j;
}
static  int sum (int m ,int m){
return i*j;
}//不会构成重载
}

在上面的代码中,虽然有两个sum()方法,他们的形参列表不同,所以系统可以正常区分出这两个方法。这样就构成了重载,并且可以看出方法的重载跟方法的权限修饰符,方法的返回值类型,都没有关系,在最后一个代码中,并不会和上面的方法构成重载,所以,可以看出构成重载和形参的变量名没有关系。
构成方法重载的方法之间的异同:
相同:都定义在同一个类中,都使用相同的方法名
不用点:参数个数不同,参数的类型不同

二. 形参个数可变的方法
从JDk1.5以后,Java就允许定义形参个数可变的参数,从而允许为方法指定数量不确定的形参。如果在方法定义时,在最后一个形参的类型后增加三点(…),则表明该形参可以接受多个参数值,多个参数值被当成数组传入。

public class ArrsExer {
	public void test (int i ,String ... books) {
		for (int i = 0 ;i < books.length; i++) {
		System.out.println(books[i]);
		}
	}
	public static void main(String[] args) {
		ArrsExer a1 = new ArrsExer();
		a1.test(1"你是谁","为什么要学Java");
		a1.test(1);//不会报错
	}//会输出你是谁
    // 为什么要学Java
    public void get (String ... er, int i ){}// 这种声明是错误的

从上面的代码中可以看出来,当调用test()方法可以传入多个字符串参数,从test()方法体来看,形参个数可变的参数本质就是一个数组参数,因此可变个数形参的方法与本类命中方法相同,形参也相同的数组不构成重载,换句话说也就是不能共存。当调用可变参数形参时,可以传零个或者一个或者多个值。可变个数形参在方法的形参中,只能声明一个形参,而且必须声明在末尾。

三.方法中的参数传递机制
Java里方法的参数传递方式只有一种:值传递。所谓的值传递,就是将实际参数值得副本传入方法中,而参数本身不会受到影响。

public void swap (int a ,int b) {
		int temp = a;
		a = b ;
		b = temp;
		System.out.println( "a = " + a + ",b = " + b);
	}
	public static void main(String[] args) {
		PrimitiveTransferTest p1 = new PrimitiveTransferTest();
		int a = 6;
		int b = 8;
		p1.swap(a,b);
		System.out.println("a = " + a + " ,b = "+b);
	}
	//调用p1方法是输出的是 a=8,b=6
	//在main方法中输出的是 a=6,b=8

从上面的运行结果来看,swap()方法中a和b的值为8 和6,交换结束后,变量a和b的值仍然为6和8.因此main()方法中的a和b,不是swap()方法中的a和b,所以swap()方法中的a和b只不过是面()a和b的复制品。下面我们来展示一下运行时候的内存图:
在这里插入图片描述
在main()方法中调用swap()方法此时main()方法还未结束,因此就将两个方法分配了两块栈区,用于保存各自的局部变量,当main()方法中调用swap()方法是传入的两个实参,实际上在sawp()方法的栈区中重新产生了两个新的变量a 和 b ,并将main() 方法中的值赋值给了这两个变量,而不是将它本身传入。此时系统存在两个a变量和两个b变量,只是存在于不用的栈区中。当然这只是在Java中基本数据类型的传递,而在Java中还有另一种类型数引用类型,也是采用的值传递的方式,引用数据类型中,他的值要么是地址值要么是null,所以它在传递的时候是将地址值传递过去,下面有几个代码:

class Number{
	int a ;
	int b ;
}
public class PrimitiveTransferTest {
	public void swap (Number nTest) {
	//定义一个临时变量来实现对 nTest对象中的数值的交换
		int temp = nTest.a;
		nTest.a = nTest.b;
		nTest.b = temp;
		System.out.println( "a = " + nTest.a + ",b = " + nTest.b);
	}
	public static void main(String[] args) {
		PrimitiveTransferTest p1 = new PrimitiveTransferTest();
		Number nTest = new Number();
		nTest.a = 6;
		nTest.b = 8;
		p1.swap(nTest);
		System.out.println("a = " + nTest.a + " ,b = "+nTest.b);
	}
}
//运行结果为a = 8,b = 6
//a = 8 ,b = 6

从上面的结果看swap()方法中的值交换成功,不仅如此,在main()方法中的值也被交换成功,这就会造成一个错觉为在传递值的时候讲整个对象传过去了,而实际并不是这样的。
程序从main()方法执行,一开始创建了一个PrimitiveTransferTest 对象是为了调用这个类中的swap()方法,这个可以忽略,接下来创建了引用变量nTest来指向 一个Number 类的对象,这就是与基本类型不用的地方,创建一个对象的时候,系统分配了两个东西:一个是堆内存中的对象本身,一个是栈内存中的引用变量。创建了一个引用变量nTest来指向 一个Number 类的对象,这样就会通过nTest这个引用变量来操作对象此时的内存结构为:
在这里插入图片描述
接下来,main()方法中调用swap()方法,main()方法没有结束,系统为两个方法分配了两个栈区。用于存放局部变量。调用swap()方法是把nTest对象作为实参传入,同样才用的值传递此时nTest中的值存放的为地址值,传过去的也就是地址值,因此形参中的这个对象得到了相同的地址值,就会指向同一个对象,接下来在方法体中通过对象去操作属性。此时的内存结构为:
在这里插入图片描述
执行完以上代码之后,swap()方法结束,swap方法中的nTest不在指向任何内存,main()中再次调用nTest的a和b依然可以输出 8,6

四. 递归方法
一个方法体中调用它自身,被称为方法递归。方法递归包含了一种隐式循环,它会重复执行某段代码,但这种重复执行无需循环控制。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

最好的文酱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值