Skip to main content
Engineering LibreTexts

14.1: Return Values

  • Page ID
    15242
  • \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \) \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)\(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\) \(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\)\(\newcommand{\AA}{\unicode[.8,0]{x212B}}\)

    When you invoke a void method, the invocation is usually on a line all by itself. For example, here is the countup method from Section 5.8:

    public static void countup(int n) {
        if (n == 0) {
            System.out.println("Blastoff!");
        } else {
            countup(n - 1);
            System.out.println(n);
        }
    }
    

    And here is how it is invoked:

    countup(3);
    System.out.println("Have a nice day.");
    

    On the other hand, when you invoke a value method, you have to do something with the return value. We usually assign it to a variable or use it as part of an expression, like this:

    double error = Math.abs(expected - actual);
    double height = radius * Math.sin(angle);
    

    Compared to void methods, value methods differ in two ways:

    • They declare the type of the return value (the return type);
    • They use at least one return statement to provide a return value.

    Here’s an example: calculateArea takes a double as a parameter and returns the area of a circle with that radius:

    public static double calculateArea(double radius) {
        double result = Math.PI * radius * radius;
        return result;
    }
    

    As usual, this method is public and static. But in the place where we are used to seeing void, we see double, which means that the return value from this method is a double.

    The last line is a new form of the return statement that includes a return value. This statement means, “return immediately from this method and use the following expression as the return value.” The expression you provide can be arbitrarily complex, so we could have written this method more concisely:

    public static double calculateArea(double radius) {
        return Math.PI * radius * radius;
    }
    

    On the other hand, temporary variables like result often make debugging easier, especially when you are stepping through code using an interactive debugger (see Appendix A.6).

    The type of the expression in the return statement must match the return type of the method. When you declare that the return type is double, you are making a promise that this method will eventually produce a double value. If you try to return with no expression, or an expression with the wrong type, the compiler will generate an error.

    Sometimes it is useful to have multiple return statements, for example, one in each branch of a conditional:

    public static double absoluteValue(double x) {
        if (x < 0) {
            return -x;
        } else {
            return x;
        }
    }
    

    Since these return statements are in a conditional statement, only one will be executed. As soon as either of them executes, the method terminates without executing any more statements.

    Code that appears after a return statement (in the same block), or any place else where it can never be executed, is called dead code. The compiler will give you an “unreachable statement” error if part of your code is dead. For example, this method contains dead code:

    public static double absoluteValue(double x) {
        if (x < 0) {
            return -x;
        } else {
            return x;
        }
        System.out.println("This line is dead.");
    }
    

    If you put return statements inside a conditional statement, you have to make sure that every possible path through the program reaches a return statement. The compiler will let you know if that’s not the case. For example, the following method is incomplete:

    public static double absoluteValue(double x) {
        if (x < 0) {
            return -x;
        } else if (x > 0) {
            return x;
        }
        // syntax error
    }
    

    When x is 0, neither condition is true, so the method ends without hitting a return statement. The error message in this case might be something like “missing return statement”, which is confusing since there are already two of them. But hopefully you will know what it means.


    This page titled 14.1: Return Values is shared under a CC BY-NC-SA 3.0 license and was authored, remixed, and/or curated by Allen B. Downey (Green Tea Press) .

    • Was this article helpful?