aspose file tools*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes Object behaviour. Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "Object behaviour." Watch "Object behaviour." New topic
Author

Object behaviour.

Nitish Bangera
Ranch Hand

Joined: Jul 15, 2009
Posts: 537

public class Animal{public void methods(){}}

class Dog extends Animal{public void methods(){}}

Now in the main, if we write

Animal A = new Dog() //We can treat a Dog as an Animal
A.methods() // Will check in Animal in compile-time and then will run Dog method in runtime.

Dog D = new Dog() //Dog is treated as Dog only.
D.methods() // Will check and run Dog method in compile and runtime respectively.

but how will this object behave on its own?
new Dog().methods();

I need to know what will it check in compile time and what will it run in runtime.


[ SCJP 6.0 - 90% ] , JSP, Servlets and Learning EJB.
Try out the programs using a TextEditor. Textpad - Java 6 api
Anastasia Sirotenko
Ranch Hand

Joined: Jul 20, 2009
Posts: 64
Nitish Bangera wrote:public class Animal{public void methods(){}}

class Dog extends Animal{public void methods(){}}

Now in the main, if we write

Animal A = new Dog() //We can treat a Dog as an Animal
A.methods() // Will check in Animal in compile-time and then will run Dog method in runtime.

Dog D = new Dog() //Dog is treated as Dog only.
D.methods() // Will check and run Dog method in compile and runtime respectively.

but how will this object behave on its own?
new Dog().methods();

I need to know what will it check in compile time and what will it run in runtime.


the only difference between the code samples

and

is that in the first sample you still will have a reference to your Dog object after your piece of code completes, and in the second sample you dont have the reference, so after executing your Dog object will be unreachable and eventually will be consumed by garbage collector. That is all, and the methods() will be called the same way in both code samples.


[SCJP 6.0]
Nitish Bangera
Ranch Hand

Joined: Jul 15, 2009
Posts: 537

Ok...Well i just got confused seeing the override of String... and String[]. Because if the Dog has a method(String[]) and Animal has method(String...) then how new Dog().method()(As it takes no arguments so String[] in Dog should not allow) behaves that i want to know. What it will check first? well the code compiles....seems it checks the Animal method and then runs dog method. I want to know is did the new Dog() check for method(String...) and then at the JVM it ran method(String[]) . Its clear when reference variables are there. But i am little confused when the objects are used for accessing methods.

Well the solution that i deduce from this is the Dog object has method(String...) takes in zero n more arguments and also method(Sting[]) which does not allow zero arguments. So when no arguments are passed, the method with String... parameter is the method which is matched and run. Is it correct???
Stephen Davies
Ranch Hand

Joined: Jul 23, 2008
Posts: 352
Hello Nitish,

Firstly would you mind using the code-tags for your example as it makes it much easier to read and assist you in your question. Thanks.

Now for your issue:





Now in the main, if we write




but how will this object behave on its own?



What is being created here is an anonymous class, which can only ever have one instance, and can only be declared
within a method or as arguments to a method.

The compiler will simply treat this as a new Dog object, it has no qualms about the type as there is no reference type (why its anonymous).
Thus the .methods will be a compiler check against the Dog object methods().

The compiler will then add a no-arg call to super() within the constructor. At runtime, the call is simply as normal as if a new Dog instance was
created and thus will operate as such. However, as it is anonymous there can only be one instance of Dog and cannot be referenced from anywhere.

This is often confusing as you can also add a body to an anonymous class, or even implement an interface, which looks like a call to new against an interface
which appears to break the rules! For example have a look at this.



The following resources, may help you:

http://docstore.mik.ua/orelly/java/javanut/ch05_05.htm
http://www.developer.com/java/other/article.php/3300881
http://java.sun.com/docs/books/tutorial/java/javaOO/objectcreation.html




Hope this helps



be a well encapsulated person, don't expose your privates, unless you public void getWife()!
Nitish Bangera
Ranch Hand

Joined: Jul 15, 2009
Posts: 537

Now it makes perfect sense. So new Dog() used on its own is creating an anonymous sub class of dog which has the methods as it inherits from dog. Also the methods are searched by the compiler in the inheritance tree.

Thanks. Stephen.
Anastasia Sirotenko
Ranch Hand

Joined: Jul 20, 2009
Posts: 64
Nitish Bangera wrote:Ok...Well i just got confused seeing the override of String... and String[]. Because if the Dog has a method(String[]) and Animal has method(String...) then how new Dog().method()(As it takes no arguments so String[] in Dog should not allow) behaves that i want to know. What it will check first? well the code compiles....seems it checks the Animal method and then runs dog method. I want to know is did the new Dog() check for method(String...) and then at the JVM it ran method(String[]) . Its clear when reference variables are there. But i am little confused when the objects are used for accessing methods.

Well the solution that i deduce from this is the Dog object has method(String...) takes in zero n more arguments and also method(Sting[]) which does not allow zero arguments. So when no arguments are passed, the method with String... parameter is the method which is matched and run. Is it correct???


If i understand the var-args well, they differ from the array only in compile time. When code compiled, the arguments you put in you var-arg method (say, method(1,2,3) ) will become an array (new int[] {1,2,3}).
So in compile time compiler searches for an appropriate method up all the hierarchy. But in runtime when you invoke Dog's method, if you had Animal String... method and Dog String[] method it will run Dog String[] method, as in runtime String... becomes String[] anyway.



Nitish Bangera
Ranch Hand

Joined: Jul 15, 2009
Posts: 537

Yeah i tried that one.....i know its ambiguous. Well i am much much clear on this subject now.


Thanks Anastasia and Stephen. I knew the String... and String[] were same at run time but i needed the info on the hierarchy accessing and yes the anonymous class behavior in terms of new Dog() on its own.
Stephen Davies
Ranch Hand

Joined: Jul 23, 2008
Posts: 352
Nitish Bangera wrote:Now it makes perfect sense. So new Dog() used on its own is creating an anonymous sub class of dog which has the methods as it inherits from dog. Also the methods are searched by the compiler in the inheritance tree.

Thanks. Stephen.


Nearly, its not creating an anonymous sublcass of Dog, it is creating a new Dog instance but anonymously. The methods are then checked at runtime against the Object. All the compiler does is the same job as for any new class declaration, it sees if it needs to add a no-arg constructor with a call to super, which is does (in this case to the Animal class), but it has no reference variables to check against for method invocations, so no it doesn't search the inheritance tree.

Nitish Bangera
Ranch Hand

Joined: Jul 15, 2009
Posts: 537

hmm one last thing then if it doesn't search the inheritance tree. How does this work


because Dog has String[] and if it doesn't search the inheritance tree then it won't get the String... and should show a compilation error. But this runs printing Dog. Why?
Vinayagar Karpagam
Ranch Hand

Joined: Apr 09, 2006
Posts: 72
We always claim that if a class extends another class,
all the inherited methods of the parent class will be accessible on a child class object.

But in this case, we have two methods which are not allowed to be kept as overloads in a class.
Then the sub-class method will override the parent class method.
This means that our sub-class Dog can have only one method, the overriding method (method(String[])).

And the compiler allows calls to both the overridden method and the overriding method. But at run-time,
it is always the overriding method that is being called.
Stephen Davies
Ranch Hand

Joined: Jul 23, 2008
Posts: 352
Vinayagar Karpagam wrote:We always claim that if a class extends another class,
all the inherited methods of the parent class will be accessible on a child class object.


Correct, Providing the access modifers for the superclass version is not private.


Vinayagar Karpagam wrote:But in this case, we have two methods which are not allowed to be kept as overloads in a class.
Then the sub-class method will override the parent class method.
This means that our sub-class Dog can have only one method, the overriding method (method(String[])).


Almost, of course the subclass of Dog may have as many methods of its own it likes. However, if it has an exact copy of a method in
its superclass (except maybe a wider modifier) then it is a valid override, which in this case it is

Vinayagar Karpagam wrote:
And the compiler allows calls to both the overridden method and the overriding method. But at run-time,
it is always the overriding method that is being called.


Correct, the compiler only checks the left hand side of the assignment (the reference types) not the object types. Thus
in this case the Class types are checked, and sees that class Animal has a method called 'method'. Thus when it sees the Dog class
type with a reference to the same method, it allows it because a Dog 'is an animal' and an animal has the method, 'method'.
It then checks the signatures to make sure they are either valid overloads(as you can also have an overloaded method of a superclass within a subclass) or valid overrides.
In this case the method signatures are the same (for the compiler) and it is passed as a valid override) However, what actually gets called
at runtime, if a method is correctly overridden, is the job of the JVM, which checks the Object type (the right hand side of the assignment)
and calls the method based on the object type (Not the Reference type) the JVM doesnt care what Reference type holds the object (that's the Compilers role), it only cares that
the object has the method called 'method'.
Stephen Davies
Ranch Hand

Joined: Jul 23, 2008
Posts: 352
To elaborate on Anastasia's post, here is a small example of my own creation:



The compiler complains at compile time here:



As we can see overloading a method between a Var-arg and an Array is not-allowed, for the simple reason that they are treated by the compiler as exactly the same.
It follows plainly that rules of overloading require at minimum, a method signature with differing argument types. However here the argument types are identical to
the Compiler, and thus to not fulfill the contract of an effective overload. It cannot be an override as in Anistasia's example, they are in the same Class. Of course if they were
in different classes they could be considered overrides, as the method signatures are identical (though one can alter the access modifiers accordingly if required dependent on the rules).
In this case then, the rules of Object method invocation, and dynamic binding as we have discussed then come into play. Example (again of my own doing):



Returns --



Nitish Bangera
Ranch Hand

Joined: Jul 15, 2009
Posts: 537

Correct, the compiler only checks the left hand side of the assignment (the reference types) not the object types. Thus
in this case the Class types are checked, and sees that class Animal has a method called 'method'. Thus when it sees the Dog class
type with a reference to the same method, it allows it because a Dog 'is an animal' and an animal has the method, 'method'.
It then checks the signatures to make sure they are either valid overloads(as you can also have an overloaded method of a superclass within a subclass) or valid overrides.


what happens when there is no reference like i asked..... new Dog().method()? What does the compiler check for?

The compiler will simply treat this as a new Dog object, it has no qualms about the type as there is no reference type (why its anonymous).
Thus the .methods will be a compiler check against the Dog object methods().


if compiler checks for dog methods then why does it compile?
Stephen Davies
Ranch Hand

Joined: Jul 23, 2008
Posts: 352
Class type only I believe (has Dog been defined somewhere and is it public)
Nitish Bangera
Ranch Hand

Joined: Jul 15, 2009
Posts: 537



here.... new Dog().method() if it sees only dog class methods then Why does it compile? Here there is no reference hence no left hand side.

This code compiles properly n outputs Dog. Now i am asking, what did the compiler see to compile it without errors?
Stephen Davies
Ranch Hand

Joined: Jul 23, 2008
Posts: 352
new Dog() is the instantiation of a new Dog Object on the heap. The Compiler doesn't encounter a reference variable, hence nothing there to do. However it checks the class type in order to insert an no-arg constructor and a call to super() , that's it. If there is no reference type, the compiler simply sets aside the memory for the new class as it usually does with new objects, but there is no problem if there is no reference variable!

Anastasia Sirotenko
Ranch Hand

Joined: Jul 20, 2009
Posts: 64
Nitish Bangera wrote:
here.... new Dog().method() if it sees only dog class methods then Why does it compile? Here there is no reference hence no left hand side.

This code compiles properly n outputs Dog. Now i am asking, what did the compiler see to compile it without errors?


Compiler sees that you attempting to cteate an object of type Dog and instantiate its method(String... s). Dog IS-A Animal, so it has Animal's String... method, tho overriden with String[] signature. So compilers sees that you create a Dog object wich has method(String... s). And it's ok for compiler. In runtime the override method(String[] s) will run.

The key point here is that
Dog d = new Dog();
d.method();

is the same as new Dog().method()

and the only difference that after you call new Dog().method() the created Dog object on the heap is lost forever while in the d.method() you still have a reference to the object and can do something with it.
Nitish Bangera
Ranch Hand

Joined: Jul 15, 2009
Posts: 537

no reference variable then also the compiler will get to the method with parameter String... .
Stephen Davies
Ranch Hand

Joined: Jul 23, 2008
Posts: 352
Nitish Bangera wrote:
no reference variable then also the compiler will get to the method with parameter String... .


What do you mean Nitish?

Nitish Bangera
Ranch Hand

Joined: Jul 15, 2009
Posts: 537

in the above program...

new Dog().method() compiles means the compiler is checking with the Animal's method(String... args) as it allows zero argument passing. Why?

if it had been Dog d = new Dog(); d.method(); then this is understood as the compiler looks in the inheritance tree for the method.
but it has no reference variables to check against for method invocations, so no it doesn't search the inheritance tree.


now if new Dog().method() runs means its getting a match with Animal's method(String... args) as dog's method(String[] args) doesn't allow zero arguments.
Vinayagar Karpagam
Ranch Hand

Joined: Apr 09, 2006
Posts: 72
Nitish Bangera wrote
This code compiles properly n outputs Dog. Now i am asking, what did the compiler see to compile it without errors?


Are you sure the code compiles? As far as I believe the compiler wouldn't allow the call when reference type is not parent type.
Stephen Davies
Ranch Hand

Joined: Jul 23, 2008
Posts: 352
Nitish Bangera wrote:in the above program...

new Dog().method() compiles means the compiler is checking with the Animal's method(String... args) as it allows zero argument passing. Why?

if it had been Dog d = new Dog(); d.method(); then this is understood as the compiler looks in the inheritance tree for the method.
but it has no reference variables to check against for method invocations, so no it doesn't search the inheritance tree.


now if new Dog().method() runs means its getting a match with Animal's method(String... args) as dog's method(String[] args) doesn't allow zero arguments.


No, the JVM checks the Object type in this case which is Dog, and finds the closest declared method called method, which it finds as part of the Dog class. In this Dog method
the method for Dog takes an Array for an argument as apposed to an Var-arg. This is totally ok
Stephen Davies
Ranch Hand

Joined: Jul 23, 2008
Posts: 352
Vinayagar Karpagam wrote:
Are you sure the code compiles? As far as I believe the compiler wouldn't allow the call when reference type is not parent type.


Have you tried, it compiles for me!
Nitish Bangera
Ranch Hand

Joined: Jul 15, 2009
Posts: 537

yes i tried the code and it compiles fine.... Well i have seen many codes using this anonymous instantiation procedure. now i want to know how the compiler checks the methods in this case?
Anastasia Sirotenko
Ranch Hand

Joined: Jul 20, 2009
Posts: 64
Nitish Bangera wrote:no reference variable then also the compiler will get to the method with parameter String... .

reference variable serves only as link to real object on the heap. That's all.
Compiler get all the information about hierarchy of the class based on the invoked class constructor. So you say new Dog() means that you creating a new Animal, particularyly Dog and expect that all the Dog's methods will be available for you. As Dog is-a Animal, all inherited Animal's methods will be available as well. Compiler does know it just from your new Dog() invocation.
Once more: the reference variable is just a link to you new Dog object, nothing more.

With the case of Animal animal = new Dog(); animal.method(); you tell compiler that all you need is Animal object and you dont care what object it realy is as far as it is-a Animal and has Animal's methods to invoke on it. so when your Animal doesn't have method(String... s) and your Dog has it, you just told compiler by Animal animal = new Dog() that you are not interested in all those Dogs or Cats and wish only general Animal implementation, so with no match for method(String... s) compiler tell you Animal have no such thing. But If your Animal has the String... method and your dog has String... or String[] method - then compiler sees you invoke existing method on Animal and at runtime will be the Dog's overriden method run.
Stephen Davies
Ranch Hand

Joined: Jul 23, 2008
Posts: 352
Nitish,

If you don't understand, of course we are here to help undoubtedly. However, if you really need to find out more and you aren't getting the information here you need, then I suggest you also do a web search, it would shed more light on your question. I provided some links above for you, did you take a look?

Good luck

Steve

Vinayagar Karpagam
Ranch Hand

Joined: Apr 09, 2006
Posts: 72
Yes, I tried. The following code doesn't compile.

Stephen Davies
Ranch Hand

Joined: Jul 23, 2008
Posts: 352
Vinayagar Karpagam wrote:Yes, I tried. The following code doesn't compile.



What was your compiler error?
Vinayagar Karpagam
Ranch Hand

Joined: Apr 09, 2006
Posts: 72
Sorry, its my eclipse settings that made the warnings displayed as error :-)
It compiles fine with a javac.
Nitish Bangera
Ranch Hand

Joined: Jul 15, 2009
Posts: 537

Stephan i understood a lot more things here and in much more clearity. Well as i understand from this case is that new Dog().method() somehow sees in the inheritance tree to get the method it wants. Otherwise it wouldn't have compiled. Well sometimes i stretch things a lot but Stephan that new dog() anonymous instantiation , that concept was a hit right to the point.

Thanks.
Anastasia Sirotenko
Ranch Hand

Joined: Jul 20, 2009
Posts: 64
See it like this:

when you call new Dog().method() it is just the same as you would do Dog d = new Dog();d.method();
But when you call new Animal() a = new Dog(); a.method() - here you just say compiler that only methods you are interested in your object are the methods it inhereted from Animal. And only those you will be able to call with a variable without cast to Dog.


just look at new Dog().method() as it was Dog d = new Dog();d.method();d = null;
Stephen Davies
Ranch Hand

Joined: Jul 23, 2008
Posts: 352
Glad to help, but you must read up on compile time versus runtime. The compiler didn't complain as there was nothing to check (no reference).
The right method called is due to the JVM at runtime with object (dynamic) binding NOT the compiler.
Stephen Davies
Ranch Hand

Joined: Jul 23, 2008
Posts: 352
Anastasia Sirotenko wrote:See it like this:

when you call new Dog().method() it is just the same as you would do Dog d = new Dog();d.method();
But when you call new Animal() a = new Dog(); a.method() - here you just call compiler that only methods you are interested in your object are the methods it inhereted from Animal. And only those you will be able to call with a variable without cast to Dog.


just look at new Dog().method() as it was Dog d = new Dog();d.method();d = null;


In addition, the methods that were checked against the super class (Animal) were checked because the compiler was checking the reference not the object. So as there was no reference type declared, the compiler checks the class type and sees its of Type Dog, and uses that as an implicit reference to a Dog object, and thus checks to see if the reference shares the correct method signatures with Animal its superclass!
Nitish Bangera
Ranch Hand

Joined: Jul 15, 2009
Posts: 537

just look at new Dog().method() as it was Dog d = new Dog();d.method();d = null;


Well originally it was the only thing i saw. But actually the behavior of not having a reference is little bit different. That is what i wanted to know. And yes one more thing is that i see a lot of things like As the reference type is checked by the compiler(left hand side). So wanted to know what if there is no left hand side only then what.
So as there was no reference type declared, the compiler checks the class type and sees its of Type Dog, and uses that as an implicit reference to a Dog object, and thus checks to see if the reference shares the correct method signatures with Animal its superclass


I think this is it.... it checks with the animal superclass and thus it compiles. At runtime its the normal story
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Object behaviour.