Why Do Constructors in Java Not Have a Return Type

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.

Can we have a return type for a constructor in Java?

On constructor not having return type

Constructor must not have a return type. By definition, if a method has a return type, it's not a constructor.

JLS 8.8 Constructor Declarations


A constructor is used in the creation of an object that is an instance of a class. [The name must match the class name, but], in all other respects, the constructor declaration looks just like a method declaration that has no result type.


On default constructors

The following snippet does give a compilation error:

class Parent {
Parent(int a){}
}

class Child extends Parent{

// DOES NOT COMPILE!!
// Implicit super constructor parent() is undefined for default constructor.
// Must define an explicit constructor

}

The reason is not because of a return type in a constructor, but because since you did not provide ANY constructor for Child, a default constructor is automatically created for you by the compiler. However, this default constructor tries to invoke the default constructor of the superclass Parent, which does NOT have a default constructor. THAT'S the source fo the compilation error.

Here's the specification for the default constructor:

JLS 8.8.9 Default Constructor


If a class contains no constructor declarations, then a default constructor that takes no parameters is automatically provided:

  • If the class being declared is the primordial class Object, then the default constructor has an empty body.
  • Otherwise, the default constructor takes no parameters and simply invokes the superclass constructor with no arguments.

The following is a simple fix:

class Parent {
Parent(int a){}
}

class Child extends Parent{

// compiles fine!
Child() {
super(42);
}

}

On methods having the same name as the constructor

The following snippet DOES compile:

// COMPILES FINE!!

class Parent {

// method has same name as class, but not a constructor
int Parent(int a) {
System.out.println("Yipppee!!!");
return 42;
}

// no explicit constructor, so default constructor is provided
}

class Child extends Parent {

// no explicit constructor, so default constructor is provided

}

There is in fact no explicit constructor in the above snippet. What you have is a regular method that has the same name as the class. This is allowed, but discouraged:

JLS 8.4 Method Declarations


A class can declare a method with the same name as the class or a field, member class or member interface of the class, but this is discouraged as a matter of style.

You will find that if you create a new Parent() or a new Child(), "Yipppee!!!" will NOT be printed to standard output. The method is not invoked upon creation since it's not a constructor.

Does a Java constructor return the Object reference?

No, actually, the constructors are compiled into the class file like methods having the name <init> and a void return type. You can see these "<init>" invocations in stack traces. The expression new Type() is compiled as an instruction new which just creates the instance of Type and an additional method invokation (invokespecial) to one of the constructors declared in Type.

The verifier will ensure that such a special method is invoked at exactly once on a newly created instance and that it is called before any other use of the object.

It’s just a programming language design decision to let constructors have no return type from the Java language point of view. After all, new Type(…) is an expression that evaluates to the newly created instance of Type and you can’t get a return value from the constructor with that programming language construct. Further, if you add a return type, Java will unconditionally assume that it is a method, even if it has the same name as the class.

That’s simply how it was defined: (It makes parsing the class definition easier)

The SimpleTypeName in the ConstructorDeclarator must be the simple name of the class that contains the constructor declaration, or a compile-time error occurs.

In all other respects, a constructor declaration looks just like a method declaration that has no result (§8.4.5).

What is the return type of a constructor in java?

Many have answered how constructors are defined in Java.

At the JVM level, static initialisers and constructors are methods which return void. Static initialisers are static methods, however constructors use this and don't need to return anything. This is because the caller is responsible for creating the object (not the constructor)

If you try to only create an object in byte code without calling a constructor you get a VerifyError. However on the oracle JVM you can use Unsafe.allocateInstance() to create an object without calling a constructor,

The static initialiser is called <cinit> which takes no arguments and the constructor is called <init>. Both have a void return type.

For the most part, this is hidden from the Java developer (unless they are generating byte code) however the only time you see these "methods" in stack traces (though you can't see a return type)

Is it possible to have a constructor with void return type?

A constructor does not have a result / return type.

If you add a result / return type to a "constructor" you turn it into a method whose name is the same as the class name. Then new won't be able to use it, and any this(...) or super(...) call in the method will be a syntax error.


For your example, you won't actually get an error. That is because Java will add a default no-args constructor for A ... because you haven't actually defined any constructors. The new in your example will actually be using the default constructor ....

If you changed your code to this:

class A {
void A() { System.err.println("hello"); }

public static void main(string arg[]) {
A a = new A();
}
}

and compiled and ran it, you should see that it DOES NOT give you any output. Remove the void and you will see output.


so here A() work as a method

It >>is<< a method. But it is not "working". As my version of your example shows ... the method is not being called at all.



Related Topics



Leave a reply



Submit