好好学Java:从零基础到项目实战
上QQ阅读APP看书,第一时间看更新

4.1.3 方法的输出参数

与输入参数相对应的则为输出参数,输出参数也被称作方法的返回值,意思是经过方法的处理最终得到的运算数值。这个返回值可能是整型数,也可能是双精度数,也可能是数组等其他类型,甚至允许不返回任何参数。与输入参数类似,输出参数也需要定义数据类型,它的返回值类型在方法名称前面定义,具体位置参见方法的定义形式“访问权限类型可选的static返回值的数据类型方法名称(参数类型参数名称)”。

这里要特别注意,即使方法不返回任何输出参数,也需定义一个名叫void的返回值类型,而不像输入参数那样若没有则直接留空。方法内部倘若中途就要结束处理,就得在指定地点添加一行“return;”,表示代码执行到这里便退出方法。对于无须返回输出参数的方法,方法末尾既可添加“return;”,又可不添加“return;”,因为此时编译器会自动结束方法。

接下来,以求数字的N次方根为例,演示如何实现一个返回值类型为void的printNsquareRoot方法。该方法的输入参数包括待求N次方根的数字,以及N次方根的整型数n。为了避免程序运行出错,必须在方法一开头就判断合法性,比如N次方根的n必须是自然数,而不能是0或负数;又比如在开偶次方根运算时,底数不能为负数。一旦输入参数的合法性校验不通过,就应当跳过剩余代码直接结束方法。据此给出方法printNsquareRoot的示例代码(完整代码见本章源码的src\com\method\function\Output.java):

    // 若不返回任何数据,也就是不存在输出参数,则返回值类型填void
    // printNsquareRoot方法用于打印指定数字的N次方根
    private static void printNsquareRoot(double number, int n) {
        if (n <= 0) {
            System.out.println("n必须为自然数");
            return;  // 不带任何参数直接返回,return语句表示该方法的剩余代码都不予执行
        } else if (n%2==0 && number<0) {
            System.out.println("不能对负数开偶次方根");
            return;  // 不带任何参数直接返回,return语句表示该方法的剩余代码都不予执行
        }
        // 下面利用牛顿迭代法求数字的N次方根
        double nsquareRoot=number;
        for (int i=0; i<n*2; i++) {  // 只需迭代2n次,即可求得较为精确的方根
            double slope=n * Math.pow(nsquareRoot, n-1);  //求导数,即切线的斜率
            nsquareRoot=nsquareRoot - (Math.pow(nsquareRoot, n)-number)/slope;
        }
        System.out.println(number+"的"+n+"次方根="+nsquareRoot);
        //return;  // 若方法的返回值类型为void,则方法末尾的return语句可加可不加
    }

因为printNsquareRoot方法不返回具体参数,所以外部可通过格式“方法名称(逗号隔开的参数列表)”调用该方法。下面便是外部调用printNsquareRoot方法的代码例子:

        // 下面的printNsquareRoot方法打印指定数字的N次方根
        printNsquareRoot(2, 2);  // 求数字2的2次方根,即对2开平方

当然,许多时候更希望求方根方法能够返回具体的方根数值,那么就要将方法的返回值类型从void改为double,并且凡是需要结束方法处理的地方,都得使用语句“return方根数值;”返回输出参数,同时方法末尾必须写明return语句。于是求方根方法改写成如下代码:

    // 若只返回一个数值,则返回值类型填该数值的变量类型
    // getNsquareRoot方法用于计算并返回指定数字的N次方根
    private static double getNsquareRoot(double number, int n) {
        if (n <= 0) {
            System.out.println("n必须为自然数");
            return 0;  // 若输入参数非法,则默认返回0
        } else if (n%2==0 && number<0) {
            System.out.println("不能对负数开偶次方根");
            return 0;  // 若输入参数非法,则默认返回0
        }
        // 下面利用牛顿迭代法求数字的N次方根
        double nsquareRoot=number;
        for (int i=0; i<n*2; i++) {  //只需迭代2n次,即可求得较为精确的方根
            double slope=n * Math.pow(nsquareRoot, n-1);  //求导数,即切线的斜率
            nsquareRoot=nsquareRoot - (Math.pow(nsquareRoot, n)-number)/slope;
        }
        return nsquareRoot;  // return后面跟着要返回的变量名称,该变量的类型与返回值类型保持一致
    }

既然改写后的getNsquareRoot方法存在输出参数,那么外部调用该方法时,应当定义一个变量用来接收方法的返回值,就像下面的代码示范的这样:

        // 下面的getNsquareRoot方法返回指定数字的N次方根
        double number1=3;
        int n1=2;
        double nsquareRoot=getNsquareRoot(number1, n1);
        System.out.println(number1+"的"+n1+"次方根="+nsquareRoot);

运行上面的方法调用代码,程序的日志输出结果如下:

3.0的2次方根=1.7320508100147274

从日志发现,getNsquareRoot方法在计算数字的偶次方根时,只会返回正值方根。这其实是不严谨的,比如3和-3都是9的平方根,然而getNsquareRoot方法只返回3,却把-3给漏掉了。因此需要对该方法加以完善,可考虑将返回值类型改为数组,这样偶次方根的正值和负值都能通过数组返回。于是重新定义一个getNsquareRootArray方法,同时新方法的返回值类型为double[],并修改相关的return语句,把返回的输出参数统统改为数组类型。经过数组改造后的getNsquareRootArray方法代码如下:

    // 若需要返回多个数值(包括0个、1个、2个以及更多),则返回值类型可以填这些数值的数组类型
    // getNsquareRootArray方法用于计算并返回指定数字的N次方根数组(比如2和-2都是4的平方根)
    private static double[] getNsquareRootArray(double number, int n) {
        if (n <= 0) {
            System.out.println("n必须为自然数");
            return new double[]{};  // 若输入参数非法,则默认返回一个空的双精度数组
        } else if (n%2==0 && number<0) {
            System.out.println("不能对负数开偶次方根");
            return new double[]{};  // 若输入参数非法,则默认返回一个空的双精度数组
        }
        // 下面利用牛顿迭代法求数字的N次方根
        double nsquareRoot=number;
        for (int i=0; i<n*2; i++) {  // 只需迭代2n次,即可求得较为精确的方根
            double slope=n * Math.pow(nsquareRoot, n-1);  //求导数,即切线的斜率
            nsquareRoot=nsquareRoot - (Math.pow(nsquareRoot, n)-number)/slope;
        }
        double[] rootArray;  // 声明一个方根数组
        if (n%2 == 0) {  // 求偶次方根,则方根有正值和负值两个数值
            rootArray=new double[]{nsquareRoot, -nsquareRoot};
        } else {  // 求奇次方根,则方根只会有一个数值
            rootArray=new double[]{nsquareRoot};
        }
        return rootArray;  // return后面跟着rootArray,其变量类型与返回值类型一样都是双精度数组
    }

外部调用getNsquareRootArray方法的时候,需要声明一个双精度数组变量,并将方法的输出参数赋值给该变量。下面是外部调用getNsquareRootArray方法的代码例子:

        // 下面的getNsquareRootArray方法返回指定数字的N次方根数组
        double number2=3;
        int n2=2;
        double[] rootArray=getNsquareRootArray(number2, n2);
        for (double root : rootArray) {
            System.out.println(number2+"的"+n2+"次方根="+root);
        }

运行上述测试代码,日志打印结果如下:

3.0的2次方根=1.7320508100147274

3.0的2次方根=-1.7320508100147274

可见调用最新的getNsquareRootArray方法,在计算数字的偶次方根时,正确返回了正负两个方根。