I'm preparing for an exam in Java and one of the questions which was on a previous exam was:"What is the main difference in object creation between Java and C++?"
I think I know the basics of object creation like for example how constructors are called and what initialization blocks do in Java and what happens when constructor of one class calls a method of another class which isn't constructed yet and so on, but I can't find anything obvious. The answer is supposed to be one or two sentences, so I don't think that description of whole object creation process in Java is what they had in mind.
Any ideas?
What is the main difference in object creation between Java and C++?
Unlike Java, in C++ objects can also be created on the stack.
For example in C++ you can write
Class obj; //object created on the stack
In Java you can write
Class obj; //obj is just a reference(not an object)
obj = new Class();// obj refers to the object
In addition to other excellent answers, one thing very important, and usually ignored/forgotten, or misunderstood (which explains why I detail the process below):
In Java, methods are virtual, even when called from the constructor (which could lead to bugs)
In C++, virtual methods are not virtual when called from the constructor (which could lead to misunderstanding)
What?
Let's imagine a Base class, with a virtual method foo().
Let's imagine a Derived class, inheriting from Base, who overrides the method foo()
The difference between C++ and Java is:
In Java, calling foo() from the Base class constructor will call Derived.foo()
In C++, calling foo() from the Base class constructor will call Base.foo()
Why?
The "bugs" for each languages are different:
In Java, calling any method in the constructor could lead to subtle bugs, as the overridden virtual method could try to access a variable which was declared/initialized in the Derived class.
Conceptually, the constructor’s job is to bring the object into existence (which is hardly an ordinary feat). Inside any constructor, the entire object might be only partially formed – you can know only that the base-class objects have been initialized, but you cannot know which classes are inherited from you. A dynamically-bound method call, however, reaches “forward” or “outward” into the inheritance hierarchy. It calls a method in a derived class. If you do this inside a constructor, you call a method that might manipulate members that haven’t been initialized yet – a sure recipe for disaster.
Bruce Eckel, http://www.codeguru.com/java/tij/tij0082.shtml
In C++, one must remember a virtual won't work as expected, as only the method of the current constructed class will be called. The reason is to avoid accessing data members or even methods that do not exist yet.
During base class construction, virtual functions never go down into derived classes. Instead, the object behaves as if it were of the base type. Informally speaking, during base class construction, virtual functions aren't.
Scott Meyers, http://www.artima.com/cppsource/nevercall.html
Besides heap/stack issues I'd say: C++ constructors have initialization lists while Java uses assignment. See http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.6 for details.
I would answer: C++ allows creating an object everywhere: on the heap, stack, member. Java forces you allocate objects on the heap, always.
In Java, the Java Virtual Machine (JVM) that executes Java code has to might1 log all objects being created (or references to them to be exact) so that the memory allocated for them can later be freed automatically by garbage collection when objects are not referenced any more.
EDIT: I'm not sure whether this can be attributed to object creation in the strict sense but it surely happens somewhen between creation and assignment to a variable, even without an explicit assignment (when you create an object without assigning it, the JVM has to auto-release it some time after that as there are no more references).
In C++, only objects created on the stack are released automatically (when they get out of scope) unless you use some mechanism that handles this for you.
1: Depending on the JVM's implementation.
There is one main design difference between constructors in C++ and Java. Other differences follow from this design decision.
The main difference is that the JVM first initializes all members to zero, before starting to execute any constructor. In C++, member initialization is part of the constructor.
The result is that during execution of a base class constructor, in C++ the members of the derived class haven't been initialized yet! In Java, they have been zero-initialized.
Hence the rule, which is explained in paercebal's answer, that virtual calls called from a constructor cannot descend into a derived class. Otherwise uninitialized members could be accessed.
Assuming that c++ uses alloc() when the new call is made, then that might be what they are
looking for. (I do not know C++, so here I can be very wrong)
Java's memory model allocates a chunk of memory when it needs it, and for each new it uses of
this pre-allocated area. This means that a new in java is just setting a pointer to a
memory segment and moving the free pointer while a new in C++ (granted it uses malloc in the background)
will result in a system call.
This makes objects cheaper to create in Java than languages using malloc;
at least when there is no initialization ocuring.
In short - creating objects in Java is cheap - don't worry about it unless you create loads of them.
Related
There are various articles out there on the interwebs that try to empirically estimate the overhead of a java.lang.Object in particular JVM implementations. For example, I've seen the size overhead of a bare Object estimated at 8 bytes in some JVMs.
What I would like to know is whether a typical JVM implementation of the extends relationship introduces incremental size overhead at every level of the class hierarchy. In other words, suppose you have a class hierarchy with N levels of subclasses. Is the overhead of the in-memory representation of a class instance O(1) or O(N)?
I imagine it is O(1) because although the size of some of the hidden fluffy stuff you need to be a Java Object (vtable, chain of classes) will grow as the inheritance hierarchy grows, they grow per-class, not per-instance, and the JVM implementation can store constant-size pointers to these entities in a constant-size header attached to every Object.
So in theory, the overhead directly attached to the in-memory representation of any Java object should be O(1) for inheritance depth N. Does anyone know if it's true in practice?
When in doubt, look at the source (well, a source; each JVM is free to choose how to do it, as the standard does not mandate any internal representation). So I had a look, and found the following comment within the implementation of JDK 7-u60's hotspot JVM:
// A Klass is the part of the klassOop that provides:
// 1: language level class object (method dictionary etc.)
// 2: provide vm dispatch behavior for the object
// Both functions are combined into one C++ class. The toplevel class "Klass"
// implements purpose 1 whereas all subclasses provide extra virtual functions
// for purpose 2.
// One reason for the oop/klass dichotomy in the implementation is
// that we don't want a C++ vtbl pointer in every object. Thus,
// normal oops don't have any virtual functions. Instead, they
// forward all "virtual" functions to their klass, which does have
// a vtbl and does the C++ dispatch depending on the object's
The way I read it, this means that, for this (very popular) implementation, object instances only store a pointer to their class. The cost, per-instance of a class, of that class having a longer or shorter inheritance chain is effectively 0. The classes themselves do take up space in memory though (but only once per class). Run-time efficiency of deep inheritance chains is another matter.
The JVM specification states
The Java Virtual Machine does not mandate any particular internal
structure for objects.
So the specification does not care how you do it. But...
In some of Oracle’s implementations of the Java Virtual Machine, a
reference to a class instance is a pointer to a handle that is itself
a pair of pointers: one to a table containing the methods of the
object and a pointer to the Class object that represents the type of
the object, and the other to the memory allocated from the heap for
the object data.
So in typical Oracle implementations it is O(1) for methods. This method table is the Method Area which is per class.
The Java Virtual Machine has a method area that is shared among all
Java Virtual Machine threads. The method area is analogous to the
storage area for compiled code of a conventional language or analogous
to the "text" segment in an operating system process. It stores
per-class structures such as the run-time constant pool, field and
method data, and the code for methods and constructors, including the
special methods (§2.9) used in class and instance initialization and
interface initialization.
Also, about method entries
The method_info structures represent all methods declared by this
class or interface type, including instance methods, class methods,
instance initialization methods (§2.9), and any class or interface
initialization method (§2.9). The methods table does not include items
representing methods that are inherited from superclasses or
superinterfaces.
An instance generally requires the following data, although it's up to the implementation exactly what to do:
the instance fields of the class and its parent classes, which I assume you don't mean to include in the term "overhead"
some means to lock the object
if the garbage collector relocates objects, then some means to record the original hash of the object (for Object.hashCode)
some means to access type information
As you guess in your question, in a "normal" Java implementation the type information is stored per-class, not per instance. Part of the definition of "type" is that two instances of the same class necessarily have the same type information, there's no obvious reason not to share it. So you would expect that per-instance overhead to be constant, not to depend on the class hierarchy.
That is to say, adding extra empty classes or interfaces to a class should not increase the size of its instances. I don't think either the language or the JVM spec actually guarantees this, though, so don't make too many assumptions about what a "non-normal" Java implementation is allowed to do.
As an aside, the second and third things on my list can be combined via cunning trickery, so that both of them together are a single pointer. The article you link to refers to references taking 4 bytes, so the 8 bytes it comes up with for an object is one pointer to type information, one field containing either a hashcode or a pointer to a monitor, and probably some flags in the lowest 2 bits of one or both of those pointer fields. Object will (you'd expect) be larger on a 64-bit Java.
Double and Integer, which extend Number, which extends Object, do not have an O(n) behavior, that is, an Integer is not 3X the size of an Object, so I think the answer is O(1). e.g. see this old SO question
in theory, the overhead directly attached to the in-memory representation of any Java object should be O(1) for inheritance depth N. Does anyone know if it's true in practice?
It can't be O(1) unless there are zero instance members at every level. Every instance member requires space per instance.
When we write a statement like Foo f = new Foo(); we know that JVM calls the Defaut ClassLoader.loadClass(), which return instance of Class , now how do we get our Foo instance from Class ?
I'm not entirely sure what you're asking, but if you're asking what code is executed when you create a new instance of a class, then the answer is that this is a primitive operation of the Java virtual machine, and there isn't any Java code involved.
The behaviour of instance creation is specified by the section 12.5. Creation of New Class Instances of the Java Language Specification.
There is also a section on 4.10.2.4. Instance Initialization Methods and Newly Created Objects in the Java Virtual Machine Specification, but that's not all that interesting.
To find out what actually happens when you create an object, you would need to choose a JVM implementation and read its source code. Alternatively, you might do what most Java programmers do, and think of it as an essentially magical operation that just works!
I know the functions are loaded only once in the memory. My doubt is... if we create an object of a class how it refer the function? What is the thing behind the object creation and function calling? Is there any pointer in the object to the function?
I believe you're looking for the term "virtual method table".
This is the mechanism that languages (compilers) use to determine what method to actually invoke when a call to a virtual function is made (and in Java all functions are virtual).
When you create an object, only it's data fields are being created (allocated). Class methods forever resides in memory during whole program run.
Does object have pointer to the method or no is language-dependent. For example, in C++ object are containing pointers to virtual methods, while normal and static methods are called just by their constant addresses.
is there any term call Virtual Constructor in Java?then where we need to use this?
Virtual Constructors are not a part of the Java language, but the term might be applied to some design patterns
For example, calling object.clone() on an object that supports it will produce a new object (much like new ClassName(object) if you have a copy constructor) and thus resembles a constructor, but is polymorphic. In "Effective Java" Joshua Bloch advocates the use of Static Factory methods as another way of achieving polymorphic object creation in certain circumstances.
For the use of the term in the C++ context look at: http://www.parashift.com/c++-faq-lite/virtual-functions.html#faq-20.8
I'm not sure what you mean by "virtual constructor." Constructors are called recursively up the class hierarchy. Every constructor must call its super-class constructor as the first thing. (The call can be omitted if it is to the no-arg constructor, in which case the compiler will automatically insert it.)
As an aside, Java doesn't have virtual methods. Or, more precisely, every instance method is virtual (in the C++ sense).
What do you mean by virtual constructors? If it is like virtual function in C++ there is no virtual constructor in java.
Not that I'm aware off. "Default Constructor " yes. Delphi has virtual constructors, most other languages does not. See the Factory pattern for something related.
Depending on the definition of virtual constructor. If by virtual constructor, you mean static method that calls a private constructor as part of some factory patterns, then yes there are virtual constructors. I have found them very useful at times, when methods must be called on self after construction. All you have to do is simply set the constructor to private, and within the class, include a static method that creates the class object instance and returns it. This is useful when methods need to be called on the object before the user is able to use it. Since it is a very bad idea to refer to self in the constructor due to the fact that the object is not fully constructed, one can use a virtual constructor to call the methods after instantiation and before the user may have access to it.
Default constructor is automatically called after an object is created.
But in Java when we allocate memory using new operator i.e. classname obj = new classname(); the constructor is automatically invoked before new allocates memory to the class member's.
The allocation starts after the class comes into physical existence but if new operator completes its process after default constructor is called, then how default constructor actually do so as the class has not come into physical existence?
Can someone explain me the same using a clear example?
The process is basically:
Memory is allocated
Execution goes up the constructor chain (i.e. all the this / super calls to other constructors) each level evaluating any arguments to the level above, but that's all
Execution goes down the constructor chain for the actual constructor bodies. So the body of the java.lang.Object constructor is executed first, then the direct subclass, etc. This is also when variable initializers are executed. (Prior to this, the variables have their default values of null etc.)
The reference is returned to whoever called new
The idea of a default constructor has no meaning at execution time. It's just a parameterless constructor which calls super() as far as the JVM is concerned.
The business about the constructor chain is exactly the same as it would be if these were methods with a first line which just chains to the next constructor along; it's just a stack of calls.
But in Java when we allocate memory using new operator i.e. classname obj=new classname(); the constructor is automatically invoked before new allocates memory to the class member's.
That is incorrect. The constructor is invoked after memory has been allocated.
#Jon Skeet's answer explains clearly the sequence of events that occur during object creation.
You may be confused by the fact that the constructors may well cause further objects to be allocated; e.g. during the execution of the declaration initializers. But these objects don't occupy memory in the original object; i.e. the object we are constructing.
If you want a definitive specification of what happens when an object is created, read the Java Language Specification - in particular JLS 12.5.
If we consider an example like
classname obj = new classname();
classname obj initialize the object and new classname(); allocates memory location for the object. If you have a constructor, then the constructor is called, otherwise default constructor is called.
Default constructor is automatically called after an object is created.
Yes (if the default (no-argument) constructor was called).
Can someone explain me the same using a clear example.
I'm not sure I understand your question to 100 % but no where in the Java Language Specification it says that the constructor should run it's code before the memory for the object has been allocated.
This is explained in great detail with an example in Section 12.5: Creation of new Class Instances in the Java Language Specification.
"...then how default constructor actually do so as the class has not come into physical existence. "
The class is already in memory, the new operator allocates memory space to hold the instance variables and parents instance variables specific to the new instance. But the class had come into physical existence before.