Why I am able to call a non-void functions without using the returned values in java?

Viewed 501

I have noticed that in java it is possible to have a statement such as: Math.random(); without any error. I expect an error when a value is returned by a function but not stored or used in any other way. Why is there no error here?

Code snippet to demonstrate :

    static int calledFn() 
    {
        return 500;
    }
    public static void main1()
    {
        calledFn();
    }
    public static void main2()
    {
        500;
    }

In the above code there is an error in the function main2() as expected, but none in main1(). But aren't both functions doing the exact same thing?
I have tried non-void functions which are both user-defined and pre-defined. It also doesn't matter whether the function returns primitive or reference data type values. In both cases there are no errors.

4 Answers

In Java, the term method is used instead of function.

When calling a method that is NOT void, it means that the method call itself is expecting a value to be returned by the corresponding method. As long as the method that is called is coded to return the specified type of variable, the value will inevitably be returned (in this case an int) regardless of whether or not it is assigned to a variable. The method call itself is what the return value goes to. If not a variable, this returned value simply isn't stored.

The bare minimum to satisfy the compiler is: method-call -> return value

Whether that returned value is used in an assignment or comparison is another story. It is sufficient to call the method by itself without assigning or using the value. When you are assigning a variable to a returned value, think of it as the returned value goes to the method call first, then the returned value goes to the variable indicated for assignment.

method-call -> return value -> assignment

The general idea of the method is to "perform the task". Then there is a thing known as application design which decides how to use that task?. And this is your answer.

Got it, If not then let's take an example.

Here is a method, which does the division:-

int divide(int a, int b){
   return a / b;
}

Now, what are the uses of this function, and the general developer will say it is only used for the division of two numbers;

But I can also use this method to generate a divide by zero exception.

Hence we can use a method for different purposes this is one of the reasons I think there is no error if we don't store the return type.

In a method, such as main1 and main2, there are supposed to be statements.

MethodDeclaration:
    MethodHeader MethodBody
MethodBody:
    Block 
    ;

Block:
    { BlockStatements(opt) }

BlockStatements:
    BlockStatement
    BlockStatements BlockStatement

BlockStatement:
    LocalVariableDeclarationStatement
    ClassDeclaration
    Statement

500; is not a statement, but Math.random(); and calledFn(); are statements.

Let's see what exactly constitutes a "statement":

Statement:
    StatementWithoutTrailingSubstatement
    LabeledStatement
    IfThenStatement
    IfThenElseStatement
    WhileStatement
    ForStatement
StatementWithoutTrailingSubstatement:
    Block
    EmptyStatement
    ExpressionStatement
    AssertStatement
    SwitchStatement
    DoStatement
    BreakStatement
    ContinueStatement
    ReturnStatement
    SynchronizedStatement
    ThrowStatement
    TryStatement

The important thing to note is that there is a kind of statement called an "expression statement". Let's see the syntax of that:

ExpressionStatement:
    StatementExpression ;

StatementExpression:
    Assignment
    PreIncrementExpression
    PreDecrementExpression
    PostIncrementExpression
    PostDecrementExpression
    MethodInvocation
    ClassInstanceCreationExpression

An ExpressionStatement is just a StatementExpression followed by a ;. Note that not all expressions are StatementExpressions. 500 is a literal, which is a kind of expression, but not a kind of StatementExpression. On the other hand, Math.random() and calledFn() are method invocations, which are StatementExpressions.

All the syntax shown are excerpts from section 18 of the Java Language Specification.

But aren't both functions doing the exact same thing?

Syntactically, they are not. In the method body of main2, there is a literal followed by a ;, which the compiler doesn't recognise as a statement. In main1, the compiler recognises calledFn() as a method invocation, and so calledFn(); is a statement.

As humans, we tend to mentally "replace" the method invocation with the value that it returns, but the compiler doesn't do that when parsing your code.

calling a method may lead to a side effect, and so calling a method without storing the result may have sense. Calling

 Math.random();
 double rand = Math.random();

instead of just

 double rand = Math.random();

provides differently distributed random numbers.

Pure value 500 without storing have no sense and is definitely an error.

Related