Differences between System.out.println() and return in Java

ObiWanShanobi picture ObiWanShanobi · Aug 23, 2014 · Viewed 29.4k times · Source

I'm trying to understand the difference, and benefits of using System.out.println() vs. return blah in a method.

It seems like System.out.println() is used to display static information, and return is a value returned from the method. Yet I'm seeing examples like the one below, where a function is used within the System.out.println() statement

System.out.println(name.substring(1, 3));

When is it right to use System.out.println() and return. Is it that return can be used by another piece of code later, whereas System.out.println() cannot?

Answer

ApproachingDarknessFish picture ApproachingDarknessFish · Aug 23, 2014

Your last sentence is effectively correct, but the distinction between these two operations is HUGE, so I'd like to provide a more in depth explanation of their differences.

The Difference:

return is an instruction that controls the flow of your program's execution. It is a fundamental part of the Java syntax. It tells the computer what part of your code to execute, and what values to use during that execution. When you return a value, you are saying "The result of calling this method is XXXX" (with 'XXXX' being the value you returned).

System.out.println is not used to control how your program executes. It is a merely way to inform the user of what is going on inside your program. System.out.println (syso for short) can print any information to the console; it doesn't matter if it's a variable, an expression, or the result of a method call. There is no limitation to "static" data.

Let's look at both of them in action:

int addInts(int arg0, int arg1)
{
    return arg0 + arg1;
}

This means that wen we call addInts in our program, it will evaluate to the sum of its arguments. So when we write addInts(3, 7), it's the same as if had simply written 3 + 7 or 10 in our source code. Nothing is printed to the console; all we've done is give our program a way of calculating something.

However, any calculations we might make are ultimately useless if all they do is sit inside the computer, so we need a way to display this information to the user. Enter syso:

System.out.println(addInts(22, 16));

The addInts method is called and returns 38. This value is placed somewhere in the computer's memory such that our program can find it.

Next, syso takes that value (38) and prints it to the console, letting the user know what value was calculated. Nothing new is calculated from this procedure, and our program continues to the next statement.

So which do I use?

In simple programs, you have so few values to keep track of that it can be tempting to just print everything that you want to know where you calculate it. For instance, if you were writing a program to do your algebra homework (I've been there) and you wrote a method to solve the quadratic equation, it might be tempting to structure it like this:

class Algebra
{
    static void quadSolve(double a, double b, double c)
    {
        double result = /* do math...  we're ignoring the negative result here*/;

        System.out.println("The solution to the quadratic equation is: " + result);
    }

    public static void main(String[] args)
    {
        quadSolve(1.0, -6.0, 9.0);
    }
}

However, this approach quickly becomes a very bad idea if you want to make your program a little more complex. Let's say one problem requires you to solve the quadratic equation and then use the result of that calculation to calculate the volume of a cylinder. In the above example, we can't do that: after we dump the value of result to the console via syso, it disappears when the quadSolve method ends. It would make much more sense if we have quadSolve return result and let the "caller" (the place quadSolve was called from) deal with handling that value. This is a much more flexible design that allows us to make our programs much more complicated with relative ease. This increased flexibility and modularity is really what makes methods useful. Here is the implementation:

class Algebra
{
    static double quadSolve(double a, double b, double c)
    {
        double result = /* do math...  we're ignoring the negative result here*/;

        return result;
    }

    public static void main(String[] args)
    {
        double x = quadSolve(1.0, -6.0, 9.0);
        //now we can do whatever we want with result: 
        //print it, negate it, pass it to another method-- whatever.
        System.out.println("The solution to the quadratic equation is: " + x);
        System.out.println("And it's square is: " + (x * x));
    }
}

I hope this clears things up. Feel free to ask if you need additional clarification.