Search code examples
javaclassreturn

Why do some java classes seem to return a value when constructed?


E.g.

import java.util.*;

public class mainXX {
    public static void main(String args[]){
    System.out.println(new Date());
    }
}

If I run this code I'm creating a new Date object but not calling any methods, it only calls the default constructor, which looks like this:

public Date() { this(System.currentTimeMillis()); }

How does the System.out.println end up printing a string date (Tue Sep 27 12:04:42 EST 2011) from this declaration as a constructor can't return a value?

I know this is a simple question but I can't figure out what is happening. Thanks, m


Solution

  • You are correct that constructors themselves do not return values, but the expression formed by applying the new operator to a constructor "call", does produce a value.

    In other words new is an operator. The expression new C ( args ) invokes the constructor C on the given arguments. The result of the new expression is the newly constructed object. It is the new operator, not the constructor, that is producing the value. (I'm being technical and saying "producing" instead of "returning" because I think that is in the spirit of your question.)

    ADDENDUM

    By way of further explanation: Constructors, do not actually "return" objects the way methods do. For example:

    public class Point {
        private double x;
        private double y;
    
        public Point (double x, double y) {
            this.x = x;
            this.y = y;
        }
    
        public double getX() {return x;}
        public double getY() {return y;}
    
        @Override public String toString() {
            return "(" + x + "," + y + ")";
        }
    }
    

    The methods getX, getY, and toString return values, so when used in an expression like this

    p.getX()
    

    a value is returned.

    The constructor has no return statement. More importantly you don't call it directly. That is you cannot say

    System.out.println(Point(1, 2));
    

    That would be an error. Instead, you use a "new-expression" which has the form new applied to the constructor name applied to an argument list. This invokes the constructor and produces a new object. For example:

    Point p = new Point(4, 3);
    

    The right hand side is a newly created point object. All I was pointing out is that nothing is returned from the constructor itself; you have to apply the new operator to get the point object.

    Because the new expression produces an object, we can apply methods directly to it. The following are all acceptable:

    new Point(4, 3)               // produces a point object
    
    new Point(4, 3).getX()        // produces 4
    
    new Point(4, 3).getY()        // produces 3
    
    new Point(4, 3).toString()    // produces "(4,3)"
    

    As other answerers have pointed out, in Java when you use an object in a context where a string is expected, the toString() method is automatically called. So

    System.out.println(new Point(4, 3))
    

    would actually print (4,3).