Varargs-Constructor cannot act as default constructor using reflection - java

FXML-View:
....
<GridPane...>
<PersonController... />
</GridPane...>
....
Class PersonController:
public PersonController(Person... personsToExclude) {
FXMLLoader.load("PersonControllerView.fxml")
this.personsToExclude = personsToExclude;
}
This code sample leads to an excpetion, because the class cannot be invoked without a default constructor (by the FXMLLoader). Now my question: You CAN use this constructor as default constructor. You can create such an object like this:
PersonConstructor pc = new PersonConstructor(); // This calls the upper constructor
Why isn't reflection able to use this constructor too? Varargs appear to be arrays internally which will be null by default if no parameter was handed over.
Was this design decision solely made to reduce complexity (it actually does reduce it a little bit for the reader) or are there any other reasons why it is important to still have a "real" default constructor?

If Oliver Charlesworth is correct, your question is really:
Why doesn't Class#newInstance() work when the class doesn't have a zero-args constructor but does have a constructor accepting a single varargs argument?
If so, I don't think we can properly answer it unless there's a quote from the design process around adding varargs to Java.
We can speculate. My speculation is: Simplicity
newInstance() is older than varargs. Until varargs were added to the language, there was no ambiguity: It could only call the nullary (zero-arguments) constructor. So they may have felt that extending it to handle constructors accepting one varargs argument was code bloat and/or scope creep for the method. After all, if you really want to do that, you can look up the relevant constructor and call that instead.
Alternately, they may have felt that newInstance's documentation ruled out calling such a constructor. Let's look at the JavaDoc for newInstance():
Creates a new instance of the class represented by this Class object. The class is instantiated as if by a new expression with an empty argument list. The class is initialized if it has not already been initialized.
Note that this method propagates any exception thrown by the nullary constructor, including a checked exception...
The first paragraph supports the idea that it could call a constructor with just one varargs argument. The second paragraph, though, mentions a "nullary" constructor specifically (though in passing). A "nullary" constructor is a zero-argument constructor, specifically, not just a constructor that can be called with no arguments.
Doing so would markedly complicate newInstance(), because rather than just looking for a constructor that accepts no arguments, it would need to look through all the constructors for one that accepts a single argument where isVarArgs is true.
Changing newInstance() to do what you're suggesting adds a new error mode: It's perfectly possible for your PersonConstructor class to have more than one constructor that can be called via new PersonConstructor():
public class PersonConstructor
{
public PersonConstructor(String... args) {
}
public PersonConstructor(Person... args) {
}
}
So which one should newInstance call? It can't decide, so it would have to throw, throwing a new error it hadn't thrown prior to the addition of varargs to the language.
All in all, if I were on the team making the decision, I would also have had newInstance() only consider true nullary constructors and not constructors accepting a single varargs argument. (I would also have updated the JavaDoc to say that. :-) )

Variable argument lists are implemented entirely in the compiler. Methods that take arrays and methods that take vararg arrays are compatible with each other - for example, you can use vararg signature
void foo(String... args)
to override a non-vararg signature
void foo(String[] args)
and vice versa (demo).
Was this design decision solely made to reduce complexity?
It is hard to guess why this particular design decision has been made, but at least part of the reason can be attributed to designer's reluctance to make changes to libraries and JVM. Java 5 update, in which variable argument feature has been introduced, opted for full backward compatibility on the bytecode level, despite the fact that it was a very big update, which introduced generics.
If you would like to work around this limitation, implement a no-argument constructor that routs the call to the constructor which takes an array:
public PersonController(Person... personsToExclude) {
}
public PersonController() {
this(new Person[0]);
}

Varargs appear to be arrays internally which will be null by default if no parameter was handed over.
This is not true. If you call a vararg method (or constructor) without any argument, the method (or constructor) is still a method with one array argument. And not null will be passed, but an empty array, as Oliver already has pointed out.
So the answer is: A vararg constructor has definitely one argument, and so it cannot be a default constructor.

Related

What is the purpose of calling the constructor of the object class in Java?

Take this simple class...
public class Gen
{
public static void main (String[] Args)
{
Gen genny = new Gen();
}
}
Section 8.8.9 of the JLS states that "If a class contains no constructor declarations, then a default constructor is implicitly declared." It also says that as long as we're not in the java.lang.object class, then the "default constructor simply invokes the superclass constructor with no arguments."
So because the class Gen extends java.lang.object, we are forced to call java.lang.object's constructor through super() as part of the implicitly-created default constructor.
Likewise...
public class Gen extends Object
{
public static void main (String[] Args)
{
Gen genny = new Gen();
}
public Gen()
{
}
}
Even if we explicitly declare a constructor for Gen, Section 8.8.7 of the JLS mandates that "if a constructor body does not begin with an explicit constructor invocation and the constructor being declared is not part of the primordial class Object, then the constructor body implicitly begins with a superclass constructor invocation "super();", an invocation of the constructor of its direct superclass that takes no arguments."
So once again, Java is going above and beyond to get us to call java.lang.object's constructor through super(). But java.lang.object's constructor literally has an empty body. It doesn't do anything. A constructor has actual purpose only 1) if you write it such that it initializes a class' instance variables or 2) if it directly/indirectly calls its superclass(es)'s constructors to initialize their instance variables. java.lang.object's constructor does neither of these things because it 1) has no instance variables and 2) is the root of the inheritance hierarchy. So it's a pointless constructor. And now, in our class Gen, we are being pointlessly forced to call a pointless constructor.
Why do this? Why can't the Java people just say "right, if the class is a direct subclass of java.lang.object then we won't implicitly define a constructor and neither will we implicitly call super() if a constructor explicitly exists." Honestly, why even have a constructor for java.lang.object in the first place if it's gonna be empty?
First of all, it is NOT necessary to write this:
public class Gen extends Object {
If a class doesn't explicitly have some other class as its direct superclass, then it implicitly extends Object. There is not need to tell the compiler that.
Yes ... all classes (apart from Object) constructors will call a constructor of their superclass. Even if the superclass is Object.
But it doesn't matter to the programmer. As the spec says, if the constructor to be called is a no-args constructor, then you don't need an explicit super call. The compiler injects a missing super() call for you if you don't include one.
Yes ... the Object constructor has an empty body in all Java implementations I have come across.
But I don't think that the JLS mandates that.
The JLS section on how objects are created states that the constructor will be called.
But it doesn't say that the compilers can't optimize away the call to the Object() constructor. And that is what they do. (The bytecode compiler is required to emit instructions for the call by JVM spec, but the JIT compiler can and will optimize it away.)
Why do they specify it in these terms?
Primarily because the spec is easier to understand and the language is easier to use if there are fewer special cases in the Java syntax and semantics.
"You can't have a super() class if the superclass is Object" would be a special case. But this complexity is not needed to make the language work, and it certainly doesn't help programmers if you force them to leave out a super() call in this context.
In addition, the current way permits a Java implementation to have a non-empty Object() constructor, if there was a good reason for doing that. (But I doubt that that was serious consideration when they designed Java.)
Either way, this is the way that Java has been since before Java 1.0, and they won't change it now. The current way doesn't actually cause any problems, or add any appreciable overheads.

Actual use of default constructor in java

Default constructors are provided by the compiler when the programmer fails to write any constructor to a class. And it is said that these constucors are used to initialize default values to the class attributes.However if the programmer provides a constructor, be it simple one like:
public class Main {
int a;
Main() { // user defined simple constructor
System.out.println("hello");
}
public static main(String[] args) {
Main obj = new Main();
}
}
In the above code the user has included a constructor. However it doesnot initialize the instance variable(a). Moreover default constructor won't be called. Then how come the variable 'a' gets initialized to it's default value.
If it is like, the default constructors do not initialize the class variables to their default values and compiler does it automatically, then what is the actual use of default constructor?
Why does the compiler add a default constructor in the case when the user fails to write a constructor?
Then how come the variable 'a' gets initialized to it's default value.
Because the language specifies that fields are initialized to their default values. Specifically, JLS 4.12.5:
Every variable in a program must have a value before its value is used:
Each class variable, instance variable, or array component is initialized with a default value when it is created (§15.9, §15.10.2):
...
For type int, the default value is zero, that is, 0.
...
Even if you did initialize it in the constructor, you could read the field beforehand, and observe its default value. For example:
Main() { // user defined simple constructor
System.out.println(a); // Prints 0
a = 1;
}
Although it is mostly hidden from you in Java, new Main() does two separate things (see JLS 15.9.4 for more detail, as it's actually more than two things):
It creates an instance of Main
Then it invokes the constructor in order to initialize that instance.
The initialization of the fields to their default values actually occurs when the instance is created (the first step, as described in the quote from JLS above); so, even if the second step of invoking a constructor didn't happen, the fields are still initialized to their default values.
Why does the compiler add a default constructor in the case when the user fails to write a constructor?
Because otherwise you wouldn't be able to create an instance of that class.
Additionally, the default constructor (like all constructors which don't call this(...) on their first line) invokes the super constructor. So, it would look something like:
Main() {
super();
}
You have to call the super constructor of a class in order to do the necessary initialization of the base class.
Default values
And it is said that these constucors are used to initialize default values to the class attributes.
That is incorrect. The constructors (including the default no-arg constructor) does not initialize the fields to their default values. This is done implicitly beforehand by the language already (see the JLS definition).
The default constructor is identical to a completely empty constructor:
Foo() {}
Technically, like other constructors, this implicitly still contains the call to the parent class constructor:
Foo() {
super();
}
Also have a look at the bytecode of public class Foo {}, which is:
public class Foo {
public Foo();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
}
You can clearly see the default constructor with code to invoke Objects constructor.
Why add it in bytecode?
Why does the compiler add a default constructor in the case when the user fails to write a constructor?
In theory it would not have to do that. However, language-design wise it is much easier to just add it to simplify the rest of the language.
For example, then you do not need any magic to make new Foo(); work, since the constructor just actually exists in the code that the JVM executes.
Same holds for more advanced topics such as the reflection API, which has methods like
Object foo = Foo.class.getConstructor().newInstance();
So if the constructor just actually exists in the bytecode, again, you do not need any magic in the JVM to make this work. It just works out of the box.
At the end of the day it was a design decision by the developers to create it in the way they did. They could have realized it differently as well.
That way however, you have a much clearer split between Java and JVM bytecode as languages. And technically you can also create classes in bytecode that do not even have constructors at all (which you can not create from within Java), which is interesting to special tools and other languages that compile to JVM bytecode (Kotlin, Groovy, Scala, Clojure, ...).
Fields are initialised with defaut values (0, 0.0, null, false, etc...)
Default behavior is useful. The alternative may be deleting it if it isn't being used or putting it in another class, or setting it as null. Most of the time though, you do want default behavior. And that is the general idea, I believe.

In Java, from where can a constructor be invoked?

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."
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.
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".
It's true. You can't write code that actually calls a constructor as follows:
class Vehicle {
Vehicle() { } // Constructor
void doSomething() {
Vehicle(); // Illegal
}
}
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."
You can use the constructor when you use the class as an object in other class.
MyClass mc = new MyClass();
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.
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.

Is it possible to disable injection of implicit constructor methods/calls?

The Java compiler generates constructors and injects super constructor calls in many circumstances.
For example,
class Foo {
Foo() {}
}
becomes
class Foo {
Foo() {
super();
}
}
I am not keen on the different circumstances and I would like to make the code explicit.
How do you disable the Java compiler from doing this if it is possible?
You cannot disable the Java compiler from making calls to super - this is one of the core principles how object orientation was designed in Java.
You might however be able to tell your IDE to always display these calls (or not).
However I recommend to stick with the standard - every Java developer knows about it and what might look a bit odd and unfamiliar to you now will become perfectly reasonable after a short time... :)
Default constructor. If you don't define a constructor for a class, a default parameterless constructor is automatically created by the compiler. The default constructor calls the default parent constructor (super()) and initializes all instance variables to default value (zero for numeric types, null for object references, and false for booleans).
Default constructor is created only if there are no constructors. If you define any constructor for your class, no default constructor is automatically created.
The first statement in any subclass constructor is ALWAYS super(). There is no need to make a call to it because it will be supplied automatically if the superclass have a default constructor without params.
If the parent class doesn't have a default constructor, you have to add an super(params) call.
Remember all classes implicitly will extend Object if they do not extend any class explicitly

C++ vs Java constructors

According to John C. Mitchell - Concepts in programming languages,
[...] Java guarantees that a
constructor is called whenever an
object is created. [...]
This is pointed as a Java peculiarity which makes it different from C++ in its behaviour. So I must argue that C++ in some cases does not call any constructor for a class even if an object for that class is created.
I think that this happens when inheritance occurs, but I cannot figure out an example for that case.
Do you know any example?
If your class defines at least one constructor, then the language will not allow you to construct an object of that type without calling a constructor.
If your class does not define a constructor, then the general rule is that the compiler-generated default constructor will be called.
As other posters have mentioned, if your class is a POD type, there are cases where your object will be left uninitialized. But this is not because the compiler "didn't call the constructor". It is because the type has no constructor (or it has one which does nothing), and is handled somewhat specially. But then again, POD types don't exist in Java, so that can't really be compared.
You can also hack around things so that the constructor is not called. For example, allocate a buffer of char's, take a pointer to the first char and cast it to the object type. Undefined behavior in most cases, of course, so it's not really "allowed", but the compiler generally won't complain.
But the bottom line is that any book which makes claims like these without being very explicit about which specific corner cases they're referring to, is most likely full of garbage. Then again, most people writing about C++ don't actually know much about the language, so it shouldn't be a surprise.
There are two cases in Java (I'm not aware of any more) in which a class' may be constructed without its constructor being called, without resulting to hacking in C or similar:
During deserialisation, serialisable classes do not have their constructor called. The no-arg constructor of the most derived non-serialisable class is invoked by the serialisation mechanism (in the Sun implementation, through non-verifiable bytecode).
When the evil Object.clone is used.
So the claim that constructors are always called in Java, is false.
For C++ types that declare constructors, it is not possible to create instances of those types without the use of a constructor. For example:
class A {
public:
A( int x ) : n( x ) {}
private:
int n;
};
it is not posible to create instancev of A without using the A(int) constructor, except by copying, which in this instance will use the synthesised copy constructor. In either case, a constructor must be used.
Java constructors can call another constructor of the same class. In C++ that is impossible. http://www.parashift.com/c++-faq-lite/ctors.html
POD's (plain old data types) are not initialized via constructors in C++:
struct SimpleClass {
int m_nNumber;
double m_fAnother;
};
SimpleClass simpleobj = { 0 };
SimpleClass simpleobj2 = { 1, 0.5 };
In both cases no constructor is called, not even a generated default constructor:
A non-const POD object declared with no initializer has an "indeterminate initial value".
Default initialization of a POD object is zero initialization.
( http://www.fnal.gov/docs/working-groups/fpcltf/Pkg/ISOcxx/doc/POD.html )
If however, SimpleClass itself defined a constructor, SimpleClass would not be a POD anymore and one of the constructors would always be called.
In C++, when an object is instantiated, a constructor of that class must be called.
There are particular cases in C++ where a constructor will not be called. In particular for POD types the implicitly defined default constructor will not be called in some situations.
struct X {
int x;
};
int main() {
X x; // implicit default constructor not called
// No guarantee in the value of x.x
X x1 = X(); // creates a temporary, calls its default constructor
// and copies that into x1. x1.x is guaranteed to be 0
}
I don't quite remember the whole set of situations where that can happen, but I seem to recall that it was mostly in this case.
To further address the issue:
This is pointed as a Java peculiarity which makes it different from C++ in its behaviour. So I must argue that C++ in some cases does not call any constructor for a class even if an object for that class is created.
Yes, with POD types you can instantiate objects and no constructor will be called. And the reason is
This is of course done for compatibility with C.
(as Neil comments out)
I think that this happens when inheritance occurs, but I cannot figure out an example for that case.
This has nothing to do with inheritance, but with the type of object being instantiated.
Java can actually allocate objects without(!) calling any constructor.
If you browse the sources of ObjectInputStream you will find that it allocates the deserialized objects without calling any constructor.
The method which allows you to do so is not part of the public API, it is in a sun.* package. However, please don't tell me it is not part of the language because of that. What you can do with public API is put together the byte stream of a deserialized object, read it in and there you go with an instance of the object whose constructor was never called!
Giving an interpretation, I have a suggestion about why the author says that for Java, without looking for any corner cases which I think don't address really the problem: you could think for example that PODs are not objects.
The fact that C++ has unsafe type casts is much more well known. For example, using a simple mixture of C and C++, you could do this:
class A {
int x;
public:
A() : X(0) {}
virtual void f() { x=x+1; }
virtual int getX() { return x; }
};
int main() {
A *a = (A *)malloc(sizeof(A));
cout << a->getX();
free(a);
}
This is a perfectly acceptable program in C++ and uses the unchecked form of type cast to avoid constructor invocation. In this case x is not initialized, so we might expect an unpredictable behaviour.
However, there might be other cases in which also Java fails to apply this rule, the mention of serialized object is perfectly reasonable and correct, even though you know for sure that the object has already been constructed in some way (unless you do some hacking on the serialized encoding of course).
Only When you overload new operator function then constructor is not called (it used to avoid constructor calling), else its in standard that constructor is invoked when object is created.
void * operator new ( size_t size )
{
void *p = malloc(size);
if(p)
return p;
else
cout<<endl<<"mem alloc failed";
}
class X
{
int X;
};
int main()
{
X *pX;
pX = reinterpret_cast<X *>(operator new(sizeof(X)*5)); // no ctor called
}
As far as I remember, Meyers in his "Effective C++" says, that the object is ONLY created when the control flow has reached his constructor's end. Otherwise it is not an object. Whenever you want to mistreat some raw memory for an actual object, you can do this:
class SomeClass
{
int Foo, int Bar;
};
SomeClass* createButNotConstruct()
{
char * ptrMem = new char[ sizeof(SomeClass) ];
return reinterpret_cast<SomeClass*>(ptrMem);
}
You won't hit any constructors here, but you may think, that you are operating a newly created object (and have a great time debugging it);
Trying to make things clear about C++. Lots of imprecise statements in answers.
In C++, a POD and a class behave the same way. A constructor is ALWAYS called. For POD, the default constructor does nothing: it does not initializes the value. But it is an error to say that no constructor is called.
Even with inheritance, constructors are called.
class A {
public: A() {}
};
class B: public A {
public: B() {} // Even if not explicitely stated, class A constructor WILL be called!
};
This seems comes down to defining the term "object" so that the statement is a tautology. Specifically, with respect to Java, he's apparently defining "object" to mean an instance of a class. With respect to C++, he (apparently) uses a broader definition of object, that includes things like primitive types that don't even have constructors.
Regardless of his definitions, however, C++ and Java are much more alike than different in this respect. Both have primitive types that don't even have constructors. Both support creation of user defined types that guarantee the invocation of constructors when objects are created.
C++ does also support creation (within very specific limits) of user defined types that don't necessarily have constructors invoked under all possible circumstances. There are tight restrictions on this, however. One of them is that the constructor must be "trivial" -- i.e. it must be a constructor that does nothing that was automatically synthesized by the compiler.
In other words, if you write a class with a constructor, the compiler is guaranteed to use it at the right times (e.g. if you write a copy constructor, all copies will be made using your copy constructor). If you write a default constructor, the compiler will use it to make all objects of that type for which no initializer is supplied, and so on.
even in the case we use statically allocated memory buffer for object creation , constructor is called.
can be seen in the following code snippet.
i haven't seen any general case yet where constructor is not called, but then there is so much to be seen :)
include
using namespace std;
class Object
{
public:
Object();
~Object();
};
inline Object::Object()
{
cout << "Constructor\n";
};
inline Object::~Object()
{
cout << "Destructor\n";
};
int main()
{
char buffer[2 * sizeof(Object)];
Object *obj = new(buffer) Object; // placement new, 1st object
new(buffer + sizeof(Object)) Object; // placement new, 2nd object
// delete obj; // DON’T DO THIS
obj[0].~Object(); // destroy 1st object
obj[1].~Object(); // destroy 2nd object
}
In Java there are some situations when the constructor is not called.
For example when a class is deserialized, the default constructor of the first non-serializable class in the type hierarchy will be called, but not the constructor of the current class. Also Object.clone avoids calling the constructor. You can also generate bytecode and do it yourself.
To understand how this is possible, even without native code magic inside the JRE, just have a look at the Java bytecode. When the new keyword is used in Java code, two bytecode instructions are generated from it - first the instance is allocated with the new instruction and then the constructor is called with the invokespecial instruction.
If you generate your own bytecode (for example with ASM), it's possible change the invokespecial instruction to call the constructor of one of the actual type's super classes' constructor (such as java.lang.Object) or even completely skip calling the constructor. The JVM will not complain about it. (The bytecode verification only checks that each constructor calls its super class's constructor, but the caller of the constructor is not checked for which constructor is called after new.)
You can also use the Objenesis library for it, so you don't need to generate the bytecode manually.
What he means is in Java, constructor of the super class is always called. This is done by calling super(...), and if you omit this compiler will insert one for you. Only exception is one constructor calls another constructor. In that case other constructor should call super(...).
This automatic code insertion by the compiler is strange actually. And if you do not have super(...) call, and the parent class does not have a constructor with no parameter it will result in a compile error. (It is odd to have a compile error for something that is automatically inserted.)
C++ will not do this automatic insertion for you.

Categories

Resources