Java之方法
1.方法的重载(overload)
概念:在一个类中,允许存在一个以上的同名方法,只要它们的参数个数和参数类型不同即可
重载的特点:与返回值类型无关,只要参数列表不同,调用方法时,根据参数列表的不同来区分
强调:“两同一不同” 两同是指同一个类,同一个方法名,一不同是指参数个数不同、参数类型不同
public class Overload5.0til { public static void main(String[] args) { OverloadUtil overloadUtil =new OverloadUtil(); overloadUtil.show(2.0); } //以下四种构成重载方法 public void show(int m,char n,double i){ System.out.println("----1----"); } public void show(double i){ System.out.println("----2----"); } public void show(int m,char n){ System.out.println("----3----"); } public void show(int m,double n,char i){ System.out.println("---4---"); } }
2.可变形参的方法
可变个数的形参:在JavaSE5.0中提供了Varargs机制,允许直接定义能和多个实参相匹配的形参,从而可以用一种更简单的方式,来传递个数可变的实参
可变个数形参的格式:数据类型...变量名 (String... number)
调用:当调用可变个数形参的方法时,传入的形参个数可以是0个、1个、2个...多个
可变个数形参的方法与本类中方法名相同、参数类型不同的方法之间构成了重载!
可变个数形参的方法与本类中方法名相同、参数类型也相同的数组之间不构成重载,换句话说,二者不共存!
public class MethodArgs { public static void main(String[] args) { MethodArgs methodArgs =new MethodArgs(); //调用3.0可变个数形参 methodArgs.show(); //这里调用的是2.0,因为已经有一个确认的形参个数和类型,自然就会调用确定的 methodArgs.show("hello"); } public void show(int i){ System.out.println("----1.0 show:int----"); } public void show(String s){ System.out.println("---2.0 show:string----"); } //可变个数形参,传入的形参个数可以是0个、1个、2个...多个 public void show(String ... strs){ System.out.println("---3.0 string ... strs---"); } }
3.方法参数的值传递机制
形参:方法声明时的参数
实参:方法调用时实际传给形参的参数值
Java的实参值如何传递给方法呢?
Java里的方法参数传递方式只有一种:值传递,也就说将实际参数值的副本(复制品)传入方法内,而参数本身不受影响
形参是基本数据类型:将实参基本数据类型的变量的“数据值”传递给形参
形参是引用数据类型:将实参引用数据类型的变量的“地址值”传递给形参
变量的赋值
/** * 首先看下变量的赋值 */ public class ValueTransferTest { public static void main(String[] args) { System.out.println("---------------基本数据类型-----------------------"); int m = 10; int n = m; //这里是将内存中m的值赋给了n(换个说法就是将m的值“复制”一份然后赋给了n) //那也就是说此时,在内存存在两个10,各自不受影响 System.out.println("m="+m+" "+"n="+n); m = 20;//所以此时修改m的值为20,对于n没有影响 System.out.println("m="+m+" "+"n="+n); System.out.println("---------------引用数据类型-----------------------"); Order order1 = new Order(); order1.orderId = 1001; Order order2 = order1;//将order1对象赋给了order2,然后打印各自的orderId都是1001,这块都明白。 System.out.println("order1.orderId的值:"+order1.orderId+" "+"order2.orderId的值:"+order2.orderId); order2.orderId = 1002;//这里修改了order2的orderId为1002,会对order1的orderId有影响吗? //从打印结果看是对order1的orderId也改变了,为什么? // 这里就需要看看这段代码Order order2 = order1 这块其实是将栈空间中order1的“地址值”赋给了order2,然后order2指向堆空间的同一个对象“实体” //该对象就是order1 new出来的对象,因此修改其他一个,另外一个也会修改! System.out.println("order1.orderId的值:"+order1.orderId+" "+"order2.orderId的值:"+order2.orderId); } } class Order{ int orderId; }
值传递机制:如果参数是基本数据类型,此时实参赋给形参的是真实存储的数据值
具体看下面这个例子:
public class ValueTransfer { public static void main(String[] args) { int m = 10; int n = 20; System.out.println("m的值是:"+m+" "+"n的值是"+n); //交换两个变量值的操作 // int temp = m; // m = n; // n = temp; // System.out.println("m的值是:"+m+" "+"n的值是"+n); ValueTransfer valueTransfer =new ValueTransfer(); valueTransfer.swap(m,n);//调用方法并打印,发现m,n的值并没有交换位置??? System.out.println("m的值是:"+m+" "+"n的值是"+n); } //将交换两个变量值的操作写在方法里面 public void swap(int m,int n){ int temp = m; m = n; n = temp; } }
内存解析:因为m、n都是基本数据类型,赋给swap(int m,int n)形参的时候,传递的是真实存储的数据值
也就是如下图所示,存在两份m、n ,但是在main方法调用swap()后执行打印的时候,发现m,n的值并没有交换位置?因为打印的是main方法里面的m、n 这也就是为啥m、n没有交换位置的原因!
值传递机制:如果参数是引用数据类型,此时实参赋给形参的是实参存储数据的”地址值”
看下面的例子:
public class ValueTransfer2 { public static void main(String[] args) { Data data = new Data(); data.m = 10; data.n = 20; System.out.println("m="+data.m+" "+"n="+data.n); ValueTransfer2 valueTransfer2 =new ValueTransfer2(); valueTransfer2.swap(data); //打印结果发现变量m,n的值变换了,因为是同一个对象data啊 System.out.println("m="+data.m+" "+"n="+data.n); } public void swap(Data data){ int temp = data.m; data.m = data.n; data.n = temp; } } class Data{ int m; int n; }
内存解析:因为在main里面new出来的data,和swap()引用的data都是指向堆空间的同一个对象“实体”。因此调用swap()方法修改了变量m、n的位置,data对象的变量数据也就修改了
4.递归方法
递归方法:一个方法体内调用它自身
方法递归包含了一种隐式的循环,它会重复执行某段代码,但这种重复执行无须循环控制
递归一定要向已知方法递归,否则这种递归就变成了无穷递归,类似于死循环
public class SumTest { public static void main(String[] args) { SumTest sumTest= new SumTest(); System.out.println(sumTest.sum(100)); System.out.println(sumTest.getProduct(5)); } //例子1:计算1-n之间所有自然数的和 public int sum(int n){ if(n ==1){ return 1; }else { return n + sum(n-1); } } //例子2:计算1-n之间所有自然数的乘积 也就是n! public int getProduct(int m){ if(m ==1){ return 1; }else { return m * getProduct(m-1); } } }