Reputation: 29
Is this statement true or false?
"The only way a constructor can be invoked is from within another constructor."
I thought a constructor could be invoked from within a method (and other places) if the call to the constructor is preceded with the keyword 'new'.
How about this statement? True or false?
"The only way a constructor can be invoked is from within another constructor (using a call to super() or this()), or from within static or instance methods, static or instance initializer blocks, or even constructors, if the call to the constructor is preceded by the keyword 'new'." Trying to invoke a constructor like you would invoke a method (using only its name) is not allowed."
Is this more accurate? "Where the call to the constructor is not preceded by the keyword 'new', the only way a constructor can be invoked is from within another constructor using this() or super() as the first statement."
Upvotes: 0
Views: 5403
Reputation: 718718
Rather than focusing on what the author of the original questions means by "invoke"1, here are the different ways that a constructor will be called.
By using the new
operator with the class name and parameters that match the constructor signature:
Foon f = new Foon(1, 2);
It is also possible to do the same thing using reflection and the Constructor
object equivalent to a new
expression, or by using the relevant JNI or JNA callbacks in native code equivalent to a new
expression. However, in all cases, the constructor invocation is conceptually happening at same point in the object creation. Hence I will treat them as identical.
By explicitly chaining to the constructor from another constructor in the same class using this(...)
.
By explicitly chaining to the constructor from a direct subclass constructor using super(...)
, or by implicitly chaining to a no-args constructor via an implied super()
in a direct subclass constructor (declared or implied).
The implicit cases are merely "syntactic sugar" for the explicit super
chaining cases.
There are a few other places where new
is invoked behind the scenes by Java from regular Java code. A couple that spring to mind are string concatenation, auto-boxing, and the JVM throwing certain exceptions; e.g.
null.toString() // implicitly creates a NullPointerException obj.
1 - ... which is unknowable unless we understand the context, including how the OP's lecturer (or text book) is using the word "invoke".
Upvotes: 2
Reputation: 49724
If you mean, directly invoking another constructor of the same object using the this(...)
or super(...)
construct (called explicit constructor invocation
), the answer is yes.
It is probable that this is what the question meant but you have to be really precise in the wording and this question isn't.
Because if by "invoke" you mean, "causing a constructor to run", then you can "invoke" a constructor with the new
keyword, which first allocates and creates the object, and then a constructor is run. In this, rather looser sense the answer is no.
But, importantly, new
does a lot more than just calling the constructor. So in the most literal sense, calling new
is not the same as invoking a constructor. Just like making tea involves pouring hot water but is not the same as simply pouring hot water.
Whether you want to make that distinction or not is up to you, or in this case the author of the question, you need to ask them.
Upvotes: 0
Reputation: 77177
Let's just go straight to the JLS, §8.8:
Constructors are invoked by class instance creation expressions (§15.9), by the conversions and concatenations caused by the string concatenation operator + (§15.18.1), and by explicit constructor invocations from other constructors (§8.8.7). [...]
Constructors are never invoked by method invocation expressions (§15.12).
Therefore, the first statement you quoted is technically false, as the JLS defines using new
as invoking the constructor.
Note that your paragraph-length statement is a combination of true and false information; you can't invoke a constructor from static or instance methods except via creating a new object.
Upvotes: 2
Reputation: 11882
This statement is false.
'Invoking a constructor' can mean three different things:
You can invoke a constructor by creating a new object with the new
operator:
String s = new String("abc");
In which case you will first allocate an object and then invoke the constructor:
NEW java/lang/String // allocate String instance
LDC "abc" // push the String constant on the stack
INVOKESPECIAL "java/lang/String"."<init>" : "(Ljava/lang/String;)V" // invoke constructor
The second way is to invoke another constructor from the same class:
class Super
{
Super(int i) { }
}
class Test extends Super {
Test() { this(1); }
// Bytecode:
INVOKESPECIAL "Test"."<init>" : "(I)V"
// ---------
The third way to invoke a constructor is to invoke one from the super class:
Test(int i) { super(i); }
// Bytecode:
INVOKESPECIAL "Super"."<init>" : "(I)V"
// ---------
}
Either way, the generated bytecode will contain an INVOKESPECIAL
instruction. This means you are literally invoking the constructor in three cases, so if you define 'invoke' by that instruction, there is more than one way to invoke a constructor.
Upvotes: 0
Reputation: 1
You can use the constructor when you use the class as an object in other class.
MyClass mc = new MyClass();
Upvotes: 0
Reputation: 716
The famous illusive constructor. It's there when it's there, and even when it's not there it's still there.
The constructor is called at object creation.
So yeah the constructor can, or more precisely will be called if you create a object using new , na matter where you use it.
That quote of yours seems to be incomplete
"The only way the constructor of the superclass of the current class can be invoked is from within the current class constructor."
Upvotes: 0
Reputation: 17132
It's true. You can't write code that actually calls a constructor as follows:
class Vehicle {
Vehicle() { } // Constructor
void doSomething() {
Vehicle(); // Illegal
}
}
Upvotes: 0