I am trying to understand how inheritance is realized inside JVM. It seems to me, that if we have the following code:
class A {
int aa;
}
class B extends A{
int bb;
}
....
B b=new B();
Inside the JVM three objects will be created:
object of B (with field int bb),
object of A (with field int aa)
object of Object.
Of course the programmers see only one object of class B. Am I right? Or is only one object created inside JVM?
What I think:
The new returns the reference to B. Why I think so is (for example) that if we override some method from A in B we can always get it using super. Besides in default constructor B the first line will be call to default constructor A in which we can call the constructor on certain object ONLY IF this object exists. Therefore a separate A object exists?
At first, the spec says that the internal structure of objects is not specified, so in theory, a JVM could internally create more than one object, where B contains only fields new to B, and a link to an A object, which contains the fields of A.
It also says something about the Oracle JVM implementation: A class instance contains three pointers. One to a method table, one to some space in heap where the data of the instances fields is, and one the Class object that instance belongs to.
You can conclude from that, that there is only one instance per object created, namely the instance of B. The method table for this instance contains all methods from B, A and Object, as well as the heap space contains all data from fields from B, A (and Object).
Here only one object will create. it is B object. But B object has state and behaviors of A object. As super type of every class is Object class, B object has Object's state and behavior too. Thanks
Classes represent a type of objects, but only instances create real objects. So only one object is created and it corresponds the result merge of class B with class A.
Related
In multiple explanations, it is explained that only one object is created during inheritance. However, during inheritance from a superclass, a subclass does not inherit its parent's private attributes.
However, when a subclass calls its parents non-static getter method, it clearly is taking the value from some parent object, not a class. Then it seems that when you create a subclass object, a superclass object is also created that stores those private attributes.
Then are there essentially two copies of inherited methods and attributes? For example, if a superclass object A has a subclass object B. Then inside B there is both a super.attribute and a this.attribute because a hidden A object is also created?
How then do constructors know the difference between attributes? For example, A has a constructor that sets a public attribute to 4. B then calls that constructor and sets the same attribute to 5. But B inherits that attribute as well, no? So does it get reset to 4? Or does the super.attribute = 4 and this.attribute = 5? Thus an attributes' value isn't inherited, but its existence is?
Java always creates only one object when you create a new instance of any class, regardless of how many other classes it extends.
When the object is being instantiated, it contains all of the public and private fields but they are all available only in their specific scope.
If you need to know more about how the object is being stored in memory, here's an example:
class A {
private boolean attribute;
}
class B extends A {
private boolean attribute;
}
B inst = new B();
In this case, inst will be a single object which contains both private fields - one can be accessed only inside A, the other - only inside B. JVM does not store fields by their names - fields are just a section of memory and JVM handles them separately.
If you want to know more about the inner representation of your class, I highly suggest Java Object Layout tool (https://github.com/openjdk/jol) or related extension for IntelliJ Idea (https://github.com/stokito/IdeaJol). In case of this example, it shows that resulting class looks like this in memory:
Instance size 24 Losses total 10 Losses internal 3 Losses external 7
Offset Size Type Class Field
0 12 (object header)
12 1 boolean A attribute < private field of A
13 3 (alignment/padding)
16 1 boolean B attribute < private field of B
17 7 (loss due to the next object)
Here are two classes,
class A
{
}
class B extends A
{
}
and A is inherited from B.What confuses me is that How many objects were created when I use the following code
A a = new B();
I know when I create an instance of B ,it will first call A's constructor and then call the constructor of B's.
Was there an instance of A been created when call A's constructor?
How many objects were created in
A a = new B();
It creates a single object, which is an instance of B. It's already a B when the A constructor executes, as you'll see if you change your code to:
class A {
public A() {
System.out.println(getClass());
}
}
class B extends A {
}
...
A a = new B(); // Prints B in the A constructor
Basically, the constructor isn't what creates an object - it's what initializes an object in the context of that class.
So you can think of the steps as:
Create object of type B
Initialize the object in the context of A (field initializers, constructor body)
Initialize the object in the context of B (field initializers, constructor body)
(with constructor chaining up the inheritance tree evaluating constructor arguments, of course... while the constructors are sort-of called going up the chain too, as the first part of any constructor has to chain to the same class or a superclass, the main part of the constructor body happens top-down).
For rather more detail about exactly what happens, see JLS 15.9.4 and JLS 12.5.
One object is created, which is a B object, which has both the aspects defined by A and the aspects defined by B. Since it incorporates all of the aspects defined by both of them, it's instanceof both A and B.
...and A is inherited from B
A is inherited by B, not from it. (The little words are the hardest in a non-native language.) B inherits from A. Some usual terms around this: "B derives from A", "B is derived from A", "A is a superclass of B", "B is a subclass of A".
Was there an instance of A been created when call A's constructor?
Despite their name, constructors don't create objects; they initialize them; and this question is why: Sometimes to correctly initialize the object, you have to call multiple constructors (one for each level in the object's inheritance hierarchy). In new B(), the JVM creates the object, then calls B with this set to that new, blank object so B can initialize it. The first thing B does is call A to let it initialize the A aspects of the object, then B initializes the B aspects of the object. E.g.:
JVM creates object.
JVM calls B
B calls A
A initializes the aspects of the object it's responsible for and returns
B initializes the aspects of the object it's responsible for and returns
Only one instance of B is created.
Constructors can be called up the chain, but each call only acts on the single instance that you're creating.
As those above me already said: Only one object is created. To clarify this you might think of the three parts of the statement you just wrote down:
A a = new B(). These are the part of declaration A a, the part of instantiation new and the part of initialization B().
If you want to read up on this topic (because perhaps not everything got clear to you), consider visiting https://docs.oracle.com/javase/tutorial/java/javaOO/objectcreation.html
I have two classes:
public class Base{
public Derived becomeDerived(){
Derived d = new Derived(this);
//set this pointer pointing to d,
//this = d; doesn't work
return d;
}
}
public class Derived extends Base{
public Derived(Base b){ }
}
Is it possible to change the runtime type of current object by its method as I show in the example?
The reason why I want to do that is providing a method for concatenating objects.
I have
public abstract class Table{
}
and
public class ComplexTable extends Table{ }
which is in fact a linked-list of Table objects.
I would like to provide a method, say Table.append(Table t) which not only modify the current Table object, but also make it ComplexTable's instance.
No.
In your example, Base wouldn't become Derived, it would return a new Derived object.
Base foo = new Base();
foo = foo.becomeDerived();
This is likely what's throwing you off, remember that the variable is not the object, just a reference to one. So while you can say foo changes from Base to Derived, the run-time type of an object didn't change, you made a new object with a different run-time type and reassigned the variable.
Edit: More in depth example. I give the objects "names" just so it's easier to understand.
Base foo = new Base();
/* After execution:
*
* Vars: | Objects:
* foo ----+---> a Base object (Name: Joe)
*/
foo = foo.becomeDerived();
/* After execution:
*
* Vars: | Objects:
* foo ----+---> a Derived object (Name: Phil)
* | a Base object (Name: Joe)(notice nothing references it)
*/
The type of "Joe" did not change. Joe was and will always be a Base object. This is what you're referring to by "run-time type of an object." However, the run-time type of variables change all the time! In this example, foo starts as Base but becomes Derived.
You cannot set this to d as this is super type of Derived d.
But it is possible to store object of type Derived like d in this case into a reference of Type Base.
You can store types of derived classes in reference of base class. But it is not changing types technically just reference holding object of derived type.
Unlike in C++
You can not change or reassign the value of this.
This was chosen to be a reserved word.So Answer is
No ,it is not possible to change the runtime type of current object
.
One more error i could find in your code is always use the Base reference variable so you can refer to objects of classes extending it.
Base b;
b=new Derived();
b=new Base();
Bad idea follows
It is possible to change the type of an object, but it relies on behaviour that is not part of the JVM spec and is thus not portable. You have been warned.
There is a class sun.misc.Unsafe that let's you read/write memory at any offset of an object. The type of an object is stored in the object's header at offset 8 on 64-bit JVMs. Thus, to change the type of the object all you need to do is to change the value at this offset. Note that the types/classes your switching between must have the same structure (reference fields on the same offsets and having the same total size). If not, the garbage collector will read non-references as references (or vice-versa) and crash you JVM.
I'm not providing working example intentionally as I'm not recommending this. Stuff like this is more suitable in C than in Java. It's really not that hard to do though, and the link I've provided together contains all information required.
Some tests I made indicates that it works on several JVMs and that the JIT is robust against these dangerous object type changes. That is no promise that it works in all systems and under all conditions.
By the way, I'm curious to hear from someone who can explain why the JIT doesn't consider the type of an object as a jit-compile-time constant, or how the JIT knows to recompile when the type of an object has changed.
In a nutshell, how and why is this possible:
Object obj=new MyClass();
Object is the superclass of all objects, therefore MyClass is a child class of Object. In general, in Java, Why is it possible to use the constructor of a child class in the parent class?
I understand how it could go the other way around, since the child has all the variables/methods of the parent class, so when you initialize them you are just initializing the variables specified in the parent constructor, that exist by definition in the child. The problem is, when you go the other way around, it is not necessarily true. A child can have variables the parent doesn't, so how is it possible to use the child constructor with the parent, when the parent does not even have the variables in the first place?
What uses does this feature have in development? I would think that if you want an instance of class B, you would declare it as B thing=new B(), and not A thing=new B(). This is probably my inexperience talking, so I would appreciate enlightenment on why and how a parent class can be initialized as one of its children.
Why is it possible to use the constructor of a child class in the
parent class?
This is not correct. When you do
Object obj = new MyClass();
Object obj; declares a reference of the type Object
and new MyClass(); returns a reference to the object it created.
So, you are instantiating a MyClass and assigning the reference to the object created to a reference of the type Object, and this is possible because MyClass is an Object.
As you say,
A child can have variables the parent doesn't
That's called extending the parent functionality (inheritance).
For your second question think about the classic Animal example: Suppose you create a Animal class and you create a method makeSound() on it.
Now you create two subclasses of Animal, Dog and Cat, that overrides the makeSound()method of Animal (a Dog barks and a Cat meows).
Imagine that you represent a room full of Animals (Dogs and Cats) using a List, and you want to make all of them makeSound(). Your list will be declared as List<Animal> because you don't know the kind of Animals that you will store.
And then you iterate over the List to call makeSound() for each Animal. It doesn't matter if the Animal is a Dogor a Cat, it will make it's sound.
And then imagine you want to add Birds to the List. Easy, isn't it?
You are thinking in terms of C++ semantics, but this is Java. In Java, all non-primitive type variables are references, not instances.
In C++, when you say
Object obj;
you allocate a new Object instance on stack or in static memory.
When you say
Object obj = new MyObject;
you invoke a constructor of Object class that takes MyObject pointer (or may be something else that MyObject can be converted to).
In Java,
Object obj;
does not create any instances of Object. It simply creates a variable that can have a reference to an Object instance, but at the moment does not refer to any. It is initialized to null.
Object obj = new MyObject();
allocates an instance of MyObject. It does not allocate a new instance of Object. It simply sets the variable to refer to the new instance. In C++ terms this is much more similar to
Object *obj = new MyObject();
So we're not constructing a parent instance from child instance. We're changing a value the variable is set to, from null to a new child instance.
First, you must get a clear understanding of things. Your example expression:
Object obj = new MyClass(); is actually a compound of two elementary operations.
The first one is creating an instance of MyClass: new MyClass(). The new keyword is basically the only way of actually obtaining an instance of a class (lets ignore runtime reflection to keep this simple), and you are literally naming what you want to create (MyClass) here by its constructor. There is no way to create anything other than what you literally named with the new keyword. The result of new is (implicitly) an instance of MyClass, but the explicit result of a new X is a reference of type X (the reference referring to the newly created instance).
Now the second operation is assigning the reference to your (new) MyObject to another reference of type Object. And this is valid because MyObject is an Object (due to inheritance).
Why would you need this?
This is an essential feature to actually make use of polymorphism. The ability to refer to any child class as its superclass is what makes polymorphism so powerful. You basically will use it everywhere where there is an aspect common to two classes, but there are also differences.
A real world example would be graphical user interfaces. There are buttons, lists, tables and panels in a window, which are all user interface elements, but each does a different thing. To present them neatly organized in a window, these elements are often nested into panels, more abstractly said into containers. Now a container doesn't care what kind of elements go into it, as long as they are components. But to handle them properly a container does need some basic information about these components, mostly how much space they occupy and how to actually draw them. So this is modelled as something like:
public abstract class Component {
public int getWidth() { ... }
public int getHeight() { ... }
public void paint(Graphics g) { ... }
}
public class Container extends Component {
public void add(Component child) { ... }
public void paint(Graphics g) {
for (Component child : children) {
child.paint(g);
}
}
}
Thats almost straight lifted out of the JDK, the point is, if you needed to refer to each Component as its concrete type, it would be impractical to build a Container, it would need extra code for each Component you decide to make (e.g. there would be an addButton, addTable and so on). So instead, Container just works with reference to Component. No matter what Component is created (e.g. Button, CheckBox, RadioButton etc.), since Container just relies on them to all be Component's, it can handle them.
Every class in Java is descended from Object. So MyClass is an Object, by definition, but a more specialized version of it. Think of it like this: every living creature is an Animal. A Cat is a special kind of animal; a specific type. Since the Cat is an Animal, you can still just call it an Animal:
Animal a = new Cat();
But doing so, with a, you can't do anything specific to a Cat, like meow() or purr(), but you can call methods which are valid for all Animals, such as breathe().
HTH
class myMobile{
public void call{
System.out.println("Mobile");
}
}
public class mainClass{
public static void main(){
Object o=new myMobile();
//here we can call methods which are common to all
// objects not specific to
// myMobile object
}
}
Because a MyClass is a Object. Note that java is special because Object is the superclass of every other class type (there is no equivalent in C++).
A more interesting example would be if you had a class or interface and one or more subclasses. This comes up all the time in OOD. Consider for example java's jdbc API: a common set of interfaces to connect and query a database that can be implemented by different concrete classes. You only need to code to the API and then at runtime use the implementation for your DB of choice.
http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html
Class Object is the root of the class hierarchy. Every class has Object as a superclass. All objects, including arrays, implement the methods of this class.
i.e. every Java class is an Object. This is why.
http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html
The Object class, defined in the java.lang package, defines and implements behavior common to all classes—including the ones that you write. In the Java platform, many classes derive directly from Object, other classes derive from some of those classes, and so on, forming a hierarchy of classes.
You have two separate things here:
The construction of a new instance
The assignment of that instance to
a variable
Since your instance of MyClass is also an instance of Object, this works well.
Consider the following, generic situation:
class A extends B implements C,D {
}
As your A is a B and also a C and a D and an Object, once you created an instance, you can (directly or indirectly) assign it to variables of all those types:
A a = new A();
B b = a;
C c = a;
D d = a;
Object o = a;
Your view on the fields or methods is limited by the type of the variable (i.E. as variable of type C, you only see the methods declared by C).
Nevertheless, your instance is always of the type you instanciated using the constructor, regardless of the variable type.
When a user defined class (A) has an Object of another user defined class (B) as one of it's data members, then:
In Java: Actually, only a reference to that instance of B is the data member of A, not the instance of B itself.
In C++: The entire instance of B is the data member. No pointers or anything. Just the whole solid instance of B itself unless it's dynamically instantiated in which case, a pointer is the data member.
Is my deduction correct or incorrect? I'm not sure myself if this is 100% correct.
Now, I'm really intrigued by this whole thing. Can you take it one step further and tell me something I missed? I mean, what is the significance of this difference? Does it mean, that the class A in Java occupies less space than the same class A implementation in C++?
Yes, you are basically correct. The Java class
class C{
D dRef; // needs to be assigned a valid object reference.
}
The dRef is assigned a newed object reference.
Will be constructed similar to the c++ class
class C2
{
D* dPointer; // needs to be assigned a valid pointer value.
};
The dPointer can be assigned a newed object pointer value.
While the c++ class
class C3
{
D dValue;
};
Will contain the entire layout size of D, created when a C3 is created.
The c++ version will likely in both scenarios occupy less space than the java version. For the java version to be usable, e.g. cObject.dRef.dMethod() a D object needs to be created, new D(). There will be overhead for both the C object as well as the instance. Garbage collection bookkeeping for instance.
The c++ variants needs only to store the pointer value in C2 (along with a new D). For C3, C3 can be the same size as D.