Constructor Returning Value

Java: How can a constructor return a value?

What you've defined isn't actually a constructor, but a method called Const. If you changed your code to something like this, it would work:

Const c = new Const();
System.out.println( c.Const( "Hello!" ) );

If no specific constructor is explicitly defined, the compiler automatically creates a no-argument constructor.

Why do constructors not return values?

What actually happens with the constructor is that the runtime uses type data generated by the compiler to determine how much space is needed to store an object instance in memory, be it on the stack or on the heap.

This space includes all members variables and the vtbl. After this space is allocated, the constructor is called as an internal part of the instantiation and initialization process to initialize the contents of the fields.

Then, when the constructor exits, the runtime returns the newly-created instance. So the reason the constructor doesn't return a value is because it's not called directly by your code, it's called by the memory allocation and object initialization code in the runtime.

Its return value (if it actually has one when compiled down to machine code) is opaque to the user - therefore, you can't specify it.

How does constructor return if it doesn't have any return type?

Constructors don't return anything. A constructor simply initializes an instance.

A new instance creation expression

new SomeExample();

produces a reference to a new instance of the specified class

A new class instance is explicitly created when evaluation of a class
instance creation expression (§15.9) causes a class to be
instantiated.

and invokes the corresponding constructor to initialize the created instance

Just before a reference to the newly created object is returned as the
result, the indicated constructor is processed to initialize the new
object using the following procedure:

  1. Assign the arguments for the constructor to newly created parameter variables for this constructor invocation.

  2. If this constructor begins with an explicit constructor invocation (§8.8.7.1) of another constructor in the same class (using this), then
    evaluate the arguments and process that constructor invocation
    recursively using these same five steps. If that constructor
    invocation completes abruptly, then this procedure completes abruptly
    for the same reason; otherwise, continue with step 5.

  3. This constructor does not begin with an explicit constructor invocation of another constructor in the same class (using this). If
    this constructor is for a class other than Object, then this
    constructor will begin with an explicit or implicit invocation of a
    superclass constructor (using super). Evaluate the arguments and
    process that superclass constructor invocation recursively using these
    same five steps. If that constructor invocation completes abruptly,
    then this procedure completes abruptly for the same reason. Otherwise,
    continue with step 4.

  4. Execute the instance initializers and instance variable initializers for this class, assigning the values of instance variable
    initializers to the corresponding instance variables, in the
    left-to-right order in which they appear textually in the source code
    for the class. If execution of any of these initializers results in an
    exception, then no further initializers are processed and this
    procedure completes abruptly with that same exception. Otherwise,
    continue with step 5.

  5. Execute the rest of the body of this constructor. If that execution completes abruptly, then this procedure completes abruptly for the
    same reason. Otherwise, this procedure completes normally.

C++ error returning value from a constructor

Constructors and destructors can't return anything. Perhaps you can store the return value in a public property of the class the constructor is for, and provide an alternate function to get that property.

Constructor returning value?

Indeed you are correct. Nothing can be done with the return value of a constructor (aside from using the Object it created).

So no, you aren't missing anything, it's the developer who wrote that code who is.

It is technically possible to use return values from constructors, if you call the function directly

$obj->__construct();

That would allow you to use the constructor's return value. However, that is highly uncommon and fairly not recommended.

Changing the return value of a constructor

A class constructor returns the value of this when it gets called by the new keyword.

See What is the 'new' keyword in JavaScript? and How does the new operator work in JavaScript? for details.

Can we change the return value to something else?

Yes, as long as it is an object, you can override the default by using return - as you did in your example code. See What values can a constructor return to avoid returning this? and What is returned from a constructor? for how that works exactly.

If yes, is it a bad practice?

Yes. Having new Car return a function and not a Car instance is weird and unexpected. People do not do this every day, and they shouldn't start doing it :-)

The only exception is the singleton pattern (which of course is problematic itself), where the constructor may return the singleton instance instead of a new one. (There are however other ways to write JS code for creating singletons, which avoid constructors altogether.)

What is the return value of an ES2015 constructor function?

According to MDN's reference on the new operator:

When the code new Foo(...) is executed, the following things happen:

  1. A new object is created, inheriting from Foo.prototype.
  2. The constructor function Foo is called with the specified arguments, and with this bound to the newly created object. new Foo is equivalent to new Foo(), i.e. if no argument list is specified, Foo is called without arguments.
  3. The object returned by the constructor function becomes the result of the whole new expression. If the constructor function doesn't explicitly return an object, the object created in step 1 is used instead. (Normally constructors don't return a value, but they can choose to do so if they want to override the normal object creation process.)

(Emphasis mine.) So it seems that the return value of the constructor function is an object, more specifically an instance of the class.

Further research showed that the return value of the constructor can be overridden by explicitly returning any object from within the constructor function (though non-object return values will be ignored, in which case the default of the newly created object reference is used.) I could not find anything to indicate that ES2015 constructors are any different than constructors prior to ES2015 classes.

This Stack Overflow post was very helpful in researching the above, particularly this article it contained a link to, though since constructor did not appear in the code in either the question nor the article, with my limited understanding of constructors that I had going into researching this they did not seem at first to answer my question. Hopefully this may clarify for others in the same situation.

Edit: The veracity of MDN's information was called into question in comments, so I researched a more definitive source. The ECMA specification says of constructors:

A constructor is an object that supports the [[Construct]] internal method.

The [[Construct]] internal method is then defined as follows:

Signature: (a List of any, Object) → Object

Description: Creates an object. Invoked via the new or super operators. The first argument to the internal method is a list containing the arguments of the operator. The second argument is the object to which the new operator was initially applied. Objects that implement this internal method are called constructors. A function object is not necessarily a constructor and such non-constructor function objects do not have a [[Construct]] internal method.

The spec states that in describing signatures such as the one above, the following convention is used: "If an internal method explicitly returns a value, its parameter list is followed by the symbol “→” and the type name of the returned value."

So, to summarize, based on the ECMA specification as quoted above, yes, constructor functions definitively do in fact return objects.



Related Topics



Leave a reply



Submit