Is a Constructor a Method?

Why a constructor is not a method.

No, it’s not. In reflection both extend Executable, but Constructor does not extend Method. It is a common misconception that constructors are methods and often asked about at job interviews.

The Java® Language Specification

The JLS always knows best. Methods and constructors are always two separate things in the JLS.

Constructors:
http://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.8

Methods:
http://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.4

Special Methods (Bytecode):
http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.9

The last one is interesting because in the bytecode a constructor is actually an instance initialization method, which is a special method. So only at bytecode level a constructor is a method. But Later, when you use reflection at runtime, it is not a method.

Reflection

A Constructor is not a Method:

Method ctor = String.class.getConstructor();
=> Type mismatch: cannot convert from Constructor<String> to Method

Misnomer: NoSuchMethodException

For some reason the method java.lang.Class.getConstructor(Class<?>…) throws a NoSuchMethodException when no matching constructor was found. There should have been a NoSuchConstructorException or NoSuchExecutableException.

Functional Programming

A Constructor is a Function, which is a kind of Method Reference:

Function<Integer, int[]> ctor = int[]::new;
IntFunction<int[]> fn = int[]::new;

But this is only true in functional programming. In Java OOP is much more important than FP, which was only added in Java 8.

How Constructors work

You use the new operator to execute a constructor. Alternatively you can use reflection. But first the JVM has to allocate memory for the new object.

Each constructor will have (explicitly or implicitly) a call to the super-constructor as the first statement. This goes up until Object() is reached, which can’t call a super-constructor (it’s the top of the hierarchy).  When super is finished all (nonstatic) members are initialized. Only then the constructor is executed. Initialization blocks are compiled into the constructor, so they are executed as well. The JVM then returns to where new was used and yields a reference to the newly created object. That’s as if it was returned, but the constructor itself doesn’t really return anything. It’s as if it was void but at the same time is also as if it returns a reference to the newly created object.

The exact procedure is hard to understand because so many blocks of code and expressions are executed. And this is a lot different from a simple call to a method. But you can use a debugger to trace the exact process.

When assigned to volatile Field

A method can be synchronized or not. But a constructor isn’t. However, you can use a sync-block on the class inside the code block of that constructor. Usually that’s not necessary. But you can get problems when multiple threads are accessing a field and you create a new instance to assign to that field. Then Java will automatically execute the constructor first and only then assign the new reference to that volatile field. No thread could see a partially constructed object. When using a nonvolatile field you could have one thread construct a new object and another thread already using it, which would end in chaos.

Properties of Methods and Constructors

Methods

  • Return something / are void
  • You can override a method
  • Are bound to an existing object, unless static
  • Can call super()-implementation
  • Can not set final fields
  • Can be static or non-static
  • Can be invoked as a method
  • Reflection: java.lang.reflect.Method

Constructor

  • Used to initialize a newly created object
  • Do not return anything
  • Are not inherited
  • You can’t override a Constructor
  • Are not bound to an existing object
  • But nested class constructors require an instance of the outer class
  • Can call super()-constructor
  • Can call constructors of same class using this()
  • Can set final fields
  • Are not static
  • Can only be invoked with new
  • Reflection: java.lang.reflect.Constructor<T>

Both

  • Have a this and a super reference
  • Can call methods on this and super reference
  • Can throw exceptions
  • Can have parameters
  • Can use the return statement

2 thoughts on “Is a Constructor a Method?”

Leave a Reply

Your email address will not be published. Required fields are marked *