0
Dog dogObj = new Dog();

Yes I know that we have to give the suitable type to the reference variable so it can reserve a place for the object's location address or whatever we put in it.

The reference variable stores a 8 byte address(number) of the real object located in the heap of register. So it's job is just to hold the address of that location. Why does it need a type then? What changes on this 8 byte after giving it a type. It still could point with it 8 byte data to that location even if it has no type.

What is the details behind this?

SirDerpington
  • 11,260
  • 4
  • 49
  • 55
Skeletor
  • 3,201
  • 4
  • 30
  • 51

3 Answers3

3

If you want a variable which can just hold any reference value, that's easy to do:

Object dogObj = new Dog();

However, if you then try to call:

dogObj.bark();

... you shouldn't be surprised that the compiler doesn't know what you're talking about. The compiler uses the declared type of the variable to know how it can be used... it's as simple as that.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Reference can point at any actual object that implement or inherit the type of this reference. Simple example is when you do `List list = new ArrayList();` – Aivean Sep 23 '14 at 17:10
  • thank you @JonSkeet. do you mean that in order to know how it can be used the object itself does not matter at the first place. i thought the reference variables job is just to point to the real location of the object not more. – Skeletor Sep 23 '14 at 17:28
  • @Skeletor: Well unless the variable had a specific type, how would the compiler know what kind of reference might be stored there? Do you understand the difference between compile-time and execution-time? – Jon Skeet Sep 23 '14 at 17:30
  • yes i know the difference between compile-time and execution-time. but what i don't understand is why does the compiler need to know what kind of reference might be stored in there. isn't it just a address number? the reference is just a number that could be anything. – Skeletor Sep 23 '14 at 20:37
  • @Skeletor: But if you've got a variable declared as type `Dog`, the VM will guarantee that the value *isn't* just anything - it will either be a null reference, or a reference to a type compatible with `Dog`... so it's safe to call `bark()`. If you only have the variable declared as type `Object`, it could a reference to a non-`Dog` object, so you *can't* call `bark()`. The variable type provides compile-time information about the *meaning* of that number. – Jon Skeet Sep 23 '14 at 21:46
2

Read this: http://www.javaranch.com/campfire/StoryCups.jsp

Then read its follow-up: http://www.javaranch.com/campfire/StoryPassBy.jsp

But basically, you need to give it a type so that the compiler knows that type it is. Note that you could also do this, which is basically what you're talking about:

Object dogObj = new Dog();

But then you could only use the methods defined in Object on that variable, since the compiler has no way of guaranteeing whether some Object is a more specific type or not.

Edit: Let's say you have two classes, Dog and Cat. Dog has a bark() method, and Cat has a meow() method.

You can do this, because as you say, a reference is a reference:

Object dog = new Dog();

But then, you won't be able to do this:

dog.bark();

Even though the Dog class has a bark() method, and the dog variable is an instance of Dog, the compiler doesn't know that. In fact, the compiler can't know what. After all, you could also do this:

Object dog = new Dog();
dog = new Cat();
dog.bark(); //good thing this is a compiler error!

And you might think, why can't the compiler figure it out? The reason for that is code like this can happen:

Object dog = new Dog();
if(Math.random() < .5){
   dog = new Cat();
}
//what type is dog now??

So the compiler can only guarantee that an Object is the type of the variable. That's why you need to give every variable a type.

Note that you can also cast your variable to explicitly tell the compiler what type something is:

Object dog = new Dog();
dog = new Cat();
((Cat)dog).meow(); //this will now work, since the compiler knows dog is a Cat!

But watch out, because if you're wrong, you'll get a runtime error:

Object dog = new Dog();
dog = new Cat();
((Dog)dog).bark(); //this won't work, since dog is actually a Cat!

I highly suggest putting together your own little test program that runs code similar to these examples, that way you can get a better idea of what's going on.

Kevin Workman
  • 41,537
  • 9
  • 68
  • 107
  • thank you @KevinWorkman for the links and explanation. the book head first java tells the same. but you said: "you need to give it a type so that the compiler knows that type it is" but doesn't the compiler get this info from the object itself. – Skeletor Sep 23 '14 at 17:24
  • @Skeletor Nope. The compiler only knows what you tell it. If you save the reference as an Object variable, then the only thing the compiler knows is that the value is **some kind of Object**. You won't be able to access any methods defined in the Dog class without casting it to a Dog variable, because later you might store a Cat instance in that same Object variable. – Kevin Workman Sep 23 '14 at 17:27
  • @Skeletor See my edited answer for a more detailed explanation. – Kevin Workman Sep 23 '14 at 17:33
  • okay @KevinWorkman i think i got it(i applied your examples). then we can say that the reference variable is not just holding the address pointing to the object it also holds the information about the object content when we declare its type. i mean the information what the object can do. right? – Skeletor Sep 23 '14 at 18:12
0

A declaration is not only memory allocation. OOP not using types would not be OOP, you are not manipulating raw bytes but objects with a precise role and a precise logic. That's what classes are for.

Dici
  • 25,226
  • 7
  • 41
  • 82