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没有交换位置的原因!

Java之方法

 值传递机制:如果参数是引用数据类型,此时实参赋给形参的是实参存储数据的”地址值”

看下面的例子:

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对象的变量数据也就修改了

Java之方法

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);
        }
    }
}