constructor invocation mechanism
Case 1)
m
is interpreted as a function return my
and taking no arguments.
To see the expected output remove ()
i.e use my m;
Case 2)
This is something better known as the "Most vexing parse".
n
is interpreted as a function returning my
that takes an argument of type pointer to function returning my
taking no arguments.
To see the expected output in this case try my n((my()));
[Instead of treating as an argument specification as in the former case the compiler would now interpret it as an expression because of the extra ()
]
My interpretation:
my n((my()))
is equivalent to my n = my()
. Now the rvalue expression my()
creates a temporary[i.e a call to the default constructor] and n
is copy initialized to that temporary object[no call to the copy-ctor because of some compiler optimization]
P.S: I am not 100% sure about the last part of my answer. Correct me if I am wrong.
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:
Assign the arguments for the constructor to newly created parameter variables for this constructor invocation.
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.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.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.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.
Why is constructor of super class invoked when we declare the object of sub class?
Because it will ensure that when a constructor is invoked, it can rely on all the fields in its superclass being initialised.
see 3.4.4 in here
Invoking virtual method in constructor: difference between Java and C++
Both approaches clearly have disadvatages:
- In Java, the call goes to a method which cannot use
this
properly because its members haven’t been initialised yet. - In C++, an unintuitive method (i.e. not the one in the derived class) is called if you don’t know how C++ constructs classes.
Why each language does what it does is an open question but both probably claim to be the “safer” option: C++’s way prevents the use of uninitialsed members; Java’s approach allows polymorphic semantics (to some extent) inside a class’ constructor (which is a perfectly valid use-case).
Can I call methods in constructor in Java?
Better design would be
public static YourObject getMyObject(File configFile){
//process and create an object configure it and return it
}
- Factory design pattern
What properties are guaranteed by constructors in Java?
All of these facts violate my intuition of what I thought a constructor is.
They shouldn't. A constructor does exactly what you think it does.
1: uninitialized objects can be leaked by sharing this
3: uninitialized objects can be leaked to another thread before they're fully constructed
The problem with the leaking of this
, starting threads in the constructor, and storing a newly constructed object where multiple threads access it without synchronization are all problems around the reordering of the initialization of non-final (and non-volatile) fields. But the initialization code is still done by the constructor. The thread that constructed the object sees the object fully. This is about when those changes are visible in other threads which is not guaranteed by the language definition.
You might be tempted to say that you know that constructor of X finished and you have a valid object, but this is untrue if you pass X to another thread - the other thread may see the uninitialized version (i.e what you just said is no different than the guarantees of calling a factory).
This is correct. It is also correct that if you have an unsynchronized object and you mutate it in one thread, other threads may or may not see the mutation. That's the nature of threaded programming. Even constructors are not safe from the need to synchronize objects properly.
2: uninitialized objects can be leaked by a subclass accessing it from the finalizer
This document is talking about finalizers and improperly being able to access an object after it has been garbage collected. By hacking subclasses and finalizers you can generate an object that is not properly constructed but it is a major hack to do so. For me this does not somehow challenge what a constructor does. Instead it demonstrates the complexity of the modern, mature, JVM. The document also shows how you can write your code to work around this hack.
What properties are guaranteed by constructors in Java?
According to the definition, a constructor:
- Allocates space for the object.
- Sets all the instance variables in the object to their default values. This includes the instance variables in the object's superclasses.
- Assigns the parameter variables for the object.
- Processes any explicit or implicit constructor invocation (a call to this() or super() in the constructor).
- Initializes variables in the class.
- Executes the rest of the constructor.
In terms of your 3 issues, #1 and #3 are, again, about when the initialization of non-final and non-volatile fields are seen by threads other than the one that constructed the object. This visibility without synchronization is not guaranteed.
The #2 issue shows a mechanism where if an exception is thrown while executing the constructor, you can override the finalize method to obtain and improperly constructed object. Constructor points 1-5 have occurred. With the hack you can bypass a portion of 6. I guess it is in the eye of the beholder if this challenges the identity of the constructor.
Java explicit constructor invocation & Instance Initializer
EDIT: It turns out the JLS is accurate after all, although it's hard to read. It's all detailed in section 12.5:
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:
Assign the arguments for the constructor to newly created parameter variables for this constructor invocation.
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.
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.
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.
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.
Note the highlighted part - the chained constructor is executed, and then we skip step 4, which would execute the instance initializer.
Reality is that the instance and field initializers are only executed once, as you can tell from your output.
Informally, I believe it's accurate to describe the procedure as:
- Keep chaining constructors within the same class (
this(...)
) until you reach a constructor body which doesn't start withthis
. - Execute the appropriate super-constructor
- Execute the instance variable initializers and the instance initializers
- Execute the body of the "innermost" constructor
- Keep popping the stack of constructor bodies until you end up with the "entry" constructor
Is that MEANS use this() within subclass's constructor will implicit remove the default call to the no-argument constructor of the superclass?
Yes. Somewhere in your chain of constructors within the class, you're guaranteed to end up with a constructor which calls super
either implicitly or explicitly. That is the only superclass constructor which is called.
EDIT: Note that the tutorial you quoted is demonstrably incorrect.
Sample class:
public class Test {
{
System.out.println("Foo");
}
public Test() {
}
public Test(int i) {
this();
}
}
Output from javap -c
:
public class Test {
public Test();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>": ()V
4: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
7: ldc #3 // String Foo
9: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
12: return
public Test(int);
Code:
0: aload_0
1: invokespecial #5 // Method "<init>":()V
4: return
}
As you can see, the constructor for Test(int)
does not have the code for the instance constructor compiled into it.
Basically, only constructors which directly call superclass constructors have instance initializer code copied into them. All other constructors will end up causing the instance initializer code to be executed via a constructor which calls the superclass constructor, of course.
How can I call the constructor of the grand parent class?
use super()
from C and from B to access A's constructor
class A {
public A() {
System.out.println("A");
}
}
class B extends A {
public B() {
super();
System.out.println("B");
}
}
class C extends B {
public C() {
super();
System.out.println("C");
}
}
public class Inheritance {
public static void main(String[] args) {
C c = new C();
}
}
Output :
A
B
C
Note:
If all are default constructor then no need to write super();
it will implicitly call it.
If there is parametrized constructor then super(parameter.. )
is needed
Related Topics
Recommended Values for Opencv Detectmultiscale() Parameters
The New Keyword "Auto"; When Should It Be Used to Declare a Variable Type
C++ - Why Static Member Function Can't Be Created with 'Const' Qualifier
Is There a Name for This Tuple-Creation Idiom
What Exactly Is Streambuf? How to Use It
Does C++ Have a Package Manager Like Npm, Pip, Gem, etc
Why Is Cuda Pinned Memory So Fast
Easy Rule to Read Complicated Const Declarations
What Is the Fastest Method for High Performance Sequential File I/O in C++
Clean C++ Granular Friend Equivalent? (Answer: Attorney-Client Idiom)
How to Convert from Int to Char*
Why Using the Const Keyword Before and After Method or Function Name
Why Do We Require Requires Requires
Using Cmake to Generate Visual Studio C++ Project Files
Difference Between Std::Result_Of and Decltype
C++11 Member Initializer List VS In-Class Initializer
What Exactly Is the Difference Between "Pass by Reference" in C and in C++